AOJ2165 Strange String Manipulation
問題リンク Strange String Manipulation
- 概要
N個の整数Ii(1<=i<=N)が与えられる。4つの整数パラメータをS, A, C, Mとする。
ここで、擬似乱数Riを次のようにとる。
R0 = S
Ri = (A * R_i-1 + C) MOD M (1 <= i <= N)
入力数列Iから次の数列Oを得る。
Oi = (Ii + Ri) MOD M
数列OのエントロピーHを最小にするようなパラメータS, A, Cを求めよ。複数ある場合はS, A, Cの辞書順で求めよ。
この問題では
M = 256
0 <= S, A, C <= 15
とする。
N < 256
- 解法
(S, A, C)の全組み合わせを試すだけです。一番最初のOiを求めるときにつかうRはR0ではなくR1であることに注意してください。また、エントロピーの大小比較のときに適当なEPSをつけないとWAになります。
- ソース
import java.util.Scanner; //Strange String Manipulation public class AOJ2165 { void run(){ Scanner sc = new Scanner(System.in); for(;;){ int n = sc.nextInt(); if(n==0)break; double min = 1<<29; int S = 0, A = 0, C = 0; int[] I = new int[n]; for(int i=0;i<n;i++)I[i]=sc.nextInt(); for(int s=0;s<16;s++)for(int a=0;a<16;a++)for(int c=0;c<16;c++){ int R = s; int[] O = new int[256]; for(int i=0;i<n;i++){ R = (a*R+c)%256; O[(I[i]+R)%256]++; } double H = 0; for(int i=0;i<256;i++)if(O[i]>0)H-=O[i]*1.0/n*Math.log(O[i]*1.0/n); if(H+1e-10<min){ min = H; S = s; A = a; C = c; } } System.out.println(S+" "+A+" "+C); } } public static void main(String[] args) { new AOJ2165().run(); } }