小白月赛E(自动计算机)

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

“WA/AC 自动机!”

给定一个长度为 mmm 的序列 aaa,分别为 a0,a1,a2...am−1a_0,a_1,a_2...a_{m-1}a0​,a1​,a2​...am−1​,一开始你拥有一个初始数为 xxx,你的第 iii 次操作会使得 x=(x+a(i−1)%m)%nx = (x + a_{(i - 1)\% m} )\%nx=(x+a(i−1)%m​)%n,请问至少多少次操作才能使 xxx 变成000。

如果无论多少次操作均无法使 x=0x = 0x=0,那么输出 −1-1−1。

输入描述:

第一行输入三个整数 nnn,mmm,xxx。

第二行输入 mmm 个整数代表序列 aaa。

保证有 1≤n,m≤1051 \le n,m \le 10^51≤n,m≤105,0≤x<n0 \le x < n0≤x<n , 0≤ai<n0 \le a_i < n0≤ai​<n 。

输出描述:

 

输出一个整数代表答案。

示例1

输入

8 3 1 1 2 3

8 3 1
1 2 3

输出

4

4

说明

 

一开始 x=1。
进行第一次操作后 x=1+1=2。
进行第二次操作后 x=2+2=4)。
进行第三次操作后 x=4+3=7(mod8)。
进行第四次操作后 x=7+1=0(mod8)。

思路:

首先取余会有循环节,而取余结果0-n-1,我们循环前n+1次,会产生n+1个结果,但取余结果却只有n种,也就是说我们进行的前n+1次必将一个循环内的所有结果都算过了。所以循环前n+1次.

对于每次循环我们先判断x是否为0,再判断这m个数中取余结果中,是否有数+x==n;

注意:

答案可能会超过int类型储存边界。

代码:

#define _CRT_SECURE_NO_WARNINGS 
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
using namespace std;
const int N =1e6;
int n, m, x;
long long a[N],b[N];
int p[N];
int main()
{  
    cin >> n >> m >> x;
    for (int i = 1; i <= m; i++)
    {
        cin >> a[i];
        b[i] = (b[i - 1]+a[i])%n;
        if (!p[b[i]])
            p[b[i]] = i;
    }
    long long ans = -1;
    x %= n;
    for (int i = 1; i <= n + 1; i++)
    {
        if (x < 0)
            x = (x % n + n) % n;
        if (x == 0)
        {
            ans = (long long )(i - 1) * m;
            break;
        }
        else if (p[n - x])
        {
            ans = (long long )(i - 1) * m + p[n - x];
            break;
        }
        x = (x + b[m]) % n;
   }
    cout << ans << endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值