链接:登录—专业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;
}