题意
输入 cc 和 nn,代表有 cc 个孩子和 nn 户邻居。
接着一行输入 nn 个数字,代表万圣节时每户邻居会给孩子们的糖果数量。
孩子们想要去若干个邻居访问,然后拿到糖果。他们想要糖果能够平分,输出访问的邻居编号。
思路
题目规定了c<=n,从这里我们可以尝试找关系。由于是求最后能平分,我们直接在读入时就可以取模。然后发现得到的数列 0 <= ai <= c-1
, 下一步我们怎么想都只能尝试对其求前缀和并取模,0 <= sumi <= c-1
,这一步出现了sumi == 0
,直接意味着这一段前缀是可以取得。然后看这个前缀和的范围,一共有c种可能性,而一旦有两个sum相等,意味着中间区间的和可以整除c,所以最极端的情况是sum取满了c-1种情况(因为不算0),而这是不可能的
因为: 1 < = ∀ s u m i < = c − 1 1<=\forall sum_i<=c-1 1<=∀sumi<=c−1, s u m i ! = s u m j sum_i != sum_j sumi!=sumj 推出 1 < = i < = c − 1 1<=i<=c-1 1<=i<=c−1,与题意 1 < = i < = n , n > = c 1<=i<=n,n>=c 1<=i<=n,n>=c不符,故必定存在一段连续区间使得 ∑ i = l r a i m o d c = 0 \sum_{i=l}^{r}a_i modc =0 ∑i=lraimodc=0.
#include "bits/stdc++.h"
#define int long long
const int mod = 1e9 + 7;
const int maxn = 1e5+10;
using namespace std;
int sum[maxn];
int vis[maxn];
signed main() {
ios ::sync_with_stdio(0);
int t;
int n,c;
while (cin >> c >> n,!(c == 0 && n == 0)){
memset(vis,0,sizeof vis);
memset(sum,0,sizeof sum);
int end = 0;
for (int i = 1; i <= n; ++i) {
int tmp;
cin >> tmp;
sum[i] = (sum[i- 1] + tmp) % c;
if (!sum[i]) end = i;
}
if (end) {
for (int i = 1; i <= end; ++i) {
cout << i <<( (end == i)?'\n':' ');
}
continue;
}
for (int i = 1; i <= n; ++i) {
if (vis[sum[i]])
{
for (int j = vis[sum[i]]+1; j <= i; ++j) {
cout << j <<( (j == i)?'\n':' ');
}
break;
} else
vis[sum[i]] = i;
}
}
}