我的思路:每一个数字对n取模,然后找两个数,使他们的和为n。二分找,复杂度是nlog(n)
代码是按照抽屉原理写的,复杂度o(n),看的讨论版:
把前缀和(mod n)求出来。
1.如果这些和中有一个0,那么我们便得到所求。
2.否则,这些和中必有两个是相等的(抽屉原理),他们相减为0,这便又找到我们想要的。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 50010;
int a[MAXN];
int sum[MAXN];
int mark[MAXN];
int fres,ed;
int main()
{
ios::sync_with_stdio(false);
int n;
fres = 0,ed = 0;
memset(mark,-1,sizeof(mark));
cin >> n;
for(int i = 1; i <= n; ++i)
{
cin >> a[i];
sum[i] = (sum[i-1]+a[i])%n;
if(sum[i] == 0 && fres == 0)
fres = i;
if(mark[sum[i]] == -1)
mark[sum[i]] = i;
else if(ed == 0)
ed = i;
}
if(fres)
{
cout << fres <<endl;
for(int i = 1; i <= fres; ++i)
cout << a[i] << endl;
return 0;
}
if(ed)
{
int l = mark[sum[ed]]+1;
int r = ed;
cout << r-l+1 << endl;
for(int i = l; i <= r; ++i)
cout << a[i] <<endl;
return 0;
}
cout << "No Solution" <<endl;
return 0;
}