暑期集训20190726 跳动(skip)

【题目描述】 福州三中的操场上有着数不尽的跳动的小朋友。 当然善于思考的你总能从中发掘出不一样的问题 福州三中的跑道是一个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的倍数就可以了。

posted @ 2019-07-29 14:38  mzWyt  阅读(171)  评论(0编辑  收藏  举报