自动计算机

这是一道思维题。要想将结果变成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;
}


全部评论

相关推荐

2 1 评论
分享
牛客网
牛客企业服务