hdoj1014 Uniform Generator

来源:互联网 发布:mysql认证考试 编辑:程序博客网 时间:2024/06/05 23:02

题意:

给出公式next = (next + step) % mod中的step和mod,问能不能在恰好mod步之内生成0~mod-1中所有的数字。

另外,有人说可以不用模拟,直接判断step和mod这两个数是否互质就可以了(即最大公约数是否等于1),是则Good Choice,反之就是Bad Choice,暂时没有了解它的原理,也许是自己的数论基础不够好吧。

代码如下(15MS,1896K):

#include <iostream>#include <fstream>#include <iomanip>      // setw#include <cstring>      // memsetusing namespace std;const int maxn(100001);bool isGenerated[maxn];int step, mod;// 题意的输出格式 void printFormat(bool flag) {    cout << setw(10) << step << setw(10) << mod << "    ";    cout << (flag ? "Good Choice" : "Bad Choice");    cout << endl << endl;}/** *   模拟这个迭代的过程 *   当在任意一个数字为起点(start)而在mod步恰好标记了整个数组,就返回成功true*   反之,如果在每一个起点都不能满足,就返回失败 */bool iterate() {    for (int start = 0; start <= step - 1; ++start) {   // 只需要到step-1就可以了,因为跳了step,起点其实是一样的         memset(isGenerated, false, sizeof isGenerated);        isGenerated[start] = true;        int needTurn = mod - 1, next = start;   // needTurn为需要'翻转'(从false转为true)的次数         while (needTurn--) {            next = (next + step) % mod;            if (isGenerated[next]) {    // 如果其中有重复'翻转'的,即不能满足在mod步内翻转mod个元素,以这个起点的这一轮就失败                 break;            } else {                isGenerated[next] = true;            }        }        if (needTurn == -1) {   // 循环了恰好needTurn次             return true;        }    }    return false;}int main() {    //ifstream cin("in.txt");    while (cin >> step >> mod) {        bool resultFlag = iterate();        printFormat(resultFlag);    }    return 0;}
0 0