UVa12169 Disgruntled Judge

例题10-2 不爽的 裁判( Disgruntled Judge, NWERC 2008, UVa12169)

有个裁判出的题太难, 总是没人做, 所以他很不爽。 有一次他终于忍不住了 , 心
想: “反正我的题没人做, 我干嘛要费那么多心思出题? 不如就输入一个随机数, 输出一个
随机数吧。 ”
于是他找了 3个整数x1、 ab, 然后按照递推公式xi=(axi-1+b) mod 10001计算出了 一个长
度为 2T的数列, 其中 T是测试数据的组数。 然后, 他把Tx1, x3, … , x2T-1写到输入文件中, x2,
x4,…, x2T写到了 输出文件中。
你的任务就是解决这个疯狂的题目 : 输入T, x1, x3, … , x2T-1, 输出 x2, x4, … , x2T。 输入保
T≤100, 且输入的所有x值为 0~ 10000的整数。 如果有多种可能的输出, 任意输出一个即可。

分析

如果知道了 a, 就可以计算出 x2, 进而根据x3=(ax2+b) mod 10001算出 b。 有了 x1、 ab
就可以在O(T)时间内计算出整个序列了 。 如果在计算过程中发现和输入矛盾, 则这个a是非
法的。 由于a是0~ 10000的整数( 因为递推公式对10001取模) , 即使枚举所有的a, 时间效
率也足够高。

 

代码

 

 1 #include<iostream>
 2 using namespace std;
 3 
 4 const int maxn = 100*2 + 5;
 5 const int M = 10001;
 6 int T, x[maxn];
 7 
 8 void solve() {
 9   ///枚举a,b
10   for(int a = 0; a < M; a++) 
11     for(int b = 0; b < M; b++) {
12       bool ok = true;
13       /**
14         根据当前的a,b 计算X(2T)
15         由X(2T-1)判断用当前a,b算得的X(2T)是否正确
16         正确,退出solve()
17         错误,继续枚举a,b
18       */
19       for(int i = 2; i <= T*2; i += 2) {
20         x[i] = (a*x[i-1] + b) % M;
21         if(i+1 <= T*2 && x[i+1] != (a*x[i] + b) % M) { ok = false; break; }
22       }
23       if(ok) return;
24     }
25 }
26 
27 int main () {
28   while(cin >> T) {
29     for(int i = 1; i <= T*2-1; i += 2) cin >> x[i];
30     solve();
31     for(int i = 2; i <= T*2; i += 2) cout << x[i] << "\n";
32   }
33   return 0;
34 }

 

posted @ 2016-05-11 11:00  赤云封天  阅读(147)  评论(0编辑  收藏  举报