【题目描述】 福州三中的操场上有着数不尽的跳动的小朋友。 当然善于思考的你总能从中发掘出不一样的问题 福州三中的跑道是一个n个格子围成的圆形,从0~n-1编号,有m个同学,第i个同学步长为a[i], 每个同学都从0开始跑步,最后有多少个格子不会被同学经过呢?
【输入数据】 第一行输入两个正整数n, m,表示操场的大小和同学的数量 第二行输入m 个用空格隔开的正整数, 分别为a[1] … a[n]
【输出数据】 一行一个整数,表示不会被经过的格子的数量
【样例输入】 10 2 4 5
【样例输出】 4
【样例解释】 第一个同学到达的位置序列为0,4,8,2,6,0,4,8,2,6…. 第二个同学到达的位置序列为0,5,0,5 … , 没有被经过的位置为1,3,7,9
【数据范围】 对于20% 的数据,m = 1 对于40% 的数据,n, m <= 2000 对于另外 10% 的数据,n是一个质数 对于100% 的数据,n, m <= 10^5, 1 <= a[i] <= n
直 接 模 拟
数据比较弱……(据出题人说数据很不好编)
#include <bits/stdc++.h> using namespace std; int sla[100010], used[100010]; int n, m; int main(){ freopen("skip.in", "r", stdin); freopen("skip.out", "w", stdout); scanf("%d%d", &n, &m); for(int i=0; i<m; i++){ scanf("%d", &sla[i]); } for(int i=0; i<n; i++) used[i] = -1; for(int i=0; i<m; i++){ int cnt=0; while(used[cnt] != i){ used[cnt] = i; cnt += sla[i]; if(cnt >= n) cnt %= n; } } int rslt=0; for(int i=0; i<n; i++) if(used[i] == -1) rslt++; printf("%d", rslt); return 0; }
比较正常的做法是,由于对于一个a[i], 只有gcd(a[i],n)的倍数的格子会被踩到,
所以只要暴力for每个出现过的gcd的倍数就可以了。