360笔试第二题 高效+简单的解法

#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
bool cmp(int a, int b)
{
	return a > b;
}
void swap(int& a, int& b)
{
	int c = a;
	a = b;
	b = c;
}
int main()
{
	int n, m;
	while (cin >> n >> m)
	{
		ifstream in("C:\\Users\\ASUS\\Desktop\\1.txt");
		in >> n >> m;
		int *number1 = new int[n];
		int *number2 = new int[n];
		int *result = new int[m];
		vector<bool> flag(n, false);
		memset(result, 0, sizeof(int)*m);
		for (int i = 0;i < n;++i)
		{
			//int temp;
			//cin >> temp;
			//number1[i] = temp;
			in >> number1[i];
		}
		for (int i = 0;i < n;++i)
		{
			//int temp;
			//cin >> temp;
			//number2[i] = temp;
			in >> number2[i];
		}
		sort(number1, number1 + n, cmp);
		sort(number2, number2 + n,cmp);
		int start = 0;
		int end = n - 1;
		for (int i = 0;i < n;++i)//循环n次
		{
			bool valid = false;
			int pos = lower_bound(number2, number2 +n,m-1-number1[i],cmp) - number2;
			int numOne = (number1[i] + number2[start]) % m;
			int numTwo = (number1[i] + number2[end]) % m;
			int numThr = INT_MIN;
			if(pos<end&&pos>start&&flag[pos])//二分查找 logN
			{
				while (1)
				{
					int tt;
					while (flag[pos])
					{
						tt = pos;
						pos = (pos + start) / 2;
					}
					if (flag[pos + 1])
						break;
					while (!flag[pos])
					{
						if (pos == tt - 1)break;
						pos = (pos + tt) / 2;
					}
				}
			}
			if (pos >= end || pos <= start)
				valid = true;
			else
			numThr = (number1[i] + number2[pos]) % m;
			if (!flag[end]&&numOne <= numTwo&&(valid||(numTwo>=numThr)))
			{
				int apos = lower_bound(number1+i, number1 + n, m - 1 - number2[end], cmp) - number1;
				if(apos==n)
				{ }
				else
				{
					int temp = (number2[end] + number1[apos]) % m;
					if (temp > numTwo)
					{
						swap(number1[i], number1[apos]);
						numTwo = temp;
					}
					sort(number1 + i + 1, number1 + n, cmp);//NlogN 快排,少数情况下进来
				}
				flag[end] = true;
				--end;
				result[numTwo]++;
				while (end - 1 >= 0&&end>=0&&flag[end])
					--end;
			}
			else if(!flag[start]&&numOne> numTwo&&(valid||(numOne>=numThr)))
			{

				int apos = lower_bound(number1 + i, number1 + n, m - 1 - number2[start], cmp) - number1;
				if (apos == n)
				{
				}
				else
				{
					int temp = (number2[start] + number1[apos]) % m;
					if (temp > numOne)
					{
						swap(number1[i], number1[apos]);
						numOne = temp;
					}
					sort(number1 + i + 1, number1 + n, cmp);//NlogN 快排,少数情况下进来
				}

				flag[start] = true;
				++start;
				result[numOne]++;
				while (flag[start]&&start+1<=n-1&&start<n)
					++start;
			}
			else if(pos<n)
			{
				int apos = lower_bound(number1 + i, number1 + n, m - 1 - number2[pos], cmp) - number1;
				if (apos == n)
				{
				}
				else
				{
					int temp = (number2[pos] + number1[apos]) % m;
					if (temp > numThr)
					{
						swap(number1[i], number1[apos]);
						numThr = temp;
					}
					sort(number1 + i + 1, number1 + n, cmp);//NlogN 快排,少数情况下进来
				}
				flag[pos] = true;
				result[numThr]++;
			}
		}
		for (int i = m - 1;i >= 0;--i)
		{
			while (result[i] != 0)
			{
				cout << i << " ";
				--result[i];
			}		
		}
		cout << endl;
	}
}

 

半夜和朋友聊天,突然说道了前两天的笔试,然后当时自己其实没有提交,当时想的是一个暴力解法,然后想了40分钟的优化,没想出来,索性就直接连暴力都没写。。许是半夜比较安静,聊到的时候突然就想到解法了。下床拿电脑敲了20分钟,运行结果正确,我没想出一些奇怪的输入测试。应该是对的吧。时间复杂度的话,那就是两次nlogn了吧。先排序,其实上面的那个排序函数也不用写,就按都是升序排也无所谓,只要排序了就行。
对其中一个数组用双指针,循环一遍就可以得到想要的组合。最后当然就是输出了。有错请指正。

改好是改好了 ,但是好像这个的最坏复杂度偏高。。。
#360公司##笔试题目#
全部评论
用一个变量记录左边可用的位置,最后优化是NlogN
点赞 回复 分享
发布于 2019-08-17 13:21
解法存在问题,诶。。。别又整回两次循环,那也太扯了,没必要…但是现在没什么改进的思路
点赞 回复 分享
发布于 2019-08-17 10:49
5进制 number1[]={3 2 2 1 1} number2[]={4 3 2 1 0} 结果应该为 4 4 4 2 0 感觉你的路还是有问题的,不能只比较两端的最大与最小的数,就比如上面这个例子,第一次循环时候,(3+4)%5=2,(3+0)%5=3,你只是取了这两个中较大的,但是(3+1)%5=4 另外,你的  int start = 0;  int end = n - 1; 这两句位置也有问题,应该在for循环之前,否则每次循环都将start和end初始化为0和n-1,不过这也不是这道题的原因
点赞 回复 分享
发布于 2019-08-17 10:39
朋友们有想到觉得比较特殊的测试可以扔过来,我测测😁
点赞 回复 分享
发布于 2019-08-17 10:14
不是点了调试相当于提交吗
点赞 回复 分享
发布于 2019-08-17 08:36
num1的一个数要遍历整个num2,这是n^2复杂度吧
点赞 回复 分享
发布于 2019-08-17 04:50
3 10 8 1 1 9 1 0
点赞 回复 分享
发布于 2019-08-17 03:49

相关推荐

野猪不是猪🐗:还是太卑微了,什么叫放弃本次面试应该说经过评估,贵公司与自己不匹配,决定不再推进后续流程
点赞 评论 收藏
分享
评论
点赞
8
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务