UVA - 408 Uniform Generator

题目大意:输入两个数 STEP 和 MOD。按公式要能产生从 0 ~ MOD-1 的伪随机数。

解题思路:
seed(x+1) = [seed(x) + step ] % mod
= { [ seed( x - 1 ) + step ] % mod + step} % mod
=[ step( x-1 ) + step + step ] % mod (取几次模的结果都会是一样的,所以取一次就好了。)
=[ step( x-1 ) + 2 * step ] % mod
…..
=[ seed(1) + x * step] % mod
其中,seed(1) = 0 ,x属于[ 1 , mod-1 ]。
所以 原式=x * step % mod;
由题意,seed( x+1 ) 与 seed( n+1 )不可以相等。
所以 x * step %mod = n * step %mod;(这里 step % mod 可能为 0 所以不能约去)
移项得 ( x - n) * step % mod = 0
0 < |x-n| < mod ,所以 (x - n)% mod != 0
所以 step 中一定不能有mod的因数,即gcd = 1

举例:若 gcd != 1
( x - n ) * step
———————————
mod
、 gcd * (step / gcd) * (x - n)
= ——————————————
、gcd * (mod / gcd )
若 (x - n) = (mod / gcd ),则可以被整除。

所以程序只要判断两数的最大公因数是否是1即可。

#include<cstdio>
int main() {
   int step, mod , res;
  while( scanf( "%d%d",&step,&mod) != EOF ) {;
    printf("%10d%10d",step,mod);
    if(mod < step) {
      res = mod;
      mod = step;
      step = res;
    }
    while(mod%step) {
      res = mod%step;
      mod = step;
      step = res;
    }
    if(step == 1) printf("    Good Choice\n\n");  //
    else printf("    Bad Choice\n\n"); 
   }
 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值