这是一道思维题。要想将结果变成0那么就需要经过x轮y次操作。首先从轮来看每次加的都是一样的,如果遍历轮的次数达到了n次,那么n+1次一定会发生循环(因为取余的存在)。
所以我们就确定的应该遍历的最大的轮数。如果超过n次还没有得到正确答案,那么循环成立之后就永远不可能得到正确答案了。所以在每一次轮数遍历的时候再去寻找有没有等于mod-x的前缀和数。如果有那么经过y次就可以得到结果。
#include <bits/stdc++.h> typedef long long ll; #define rep(i,a,n) for(int i=a;i<=n;i++) using namespace std; const int maxn = 1e5+10; ll mod; ll pre[maxn]; //map散列,快速找到所需要的数。 map<ll, ll> mp; int main() { ll mod, m, x; cin>>mod>>m>>x; rep(i, 1, m) { cin>>pre[i]; pre[i] = (pre[i] + pre[i-1])%mod; //如果没有相同在才进行填充,目的是要保持最近。 if (!mp.count(pre[i])) mp[pre[i]] = i; } //开始n轮的循环计算,如果超过n次还有没能得出正确答案,那么根据鸽巢原理就会产生循环。 //所以只需要验证前n轮是否可以产生答案即可。 if (x==0) { cout<<0; return 0; } ll ans = -1; rep(i, 1, mod) { int need = mod - x; if (mp.count(need)) { ans = m*(i-1)+mp[need]; break; } x = (x+pre[m])%mod; } cout<<ans; return 0; }