2010年5月9日日曜日

Google Code Jam 2010 Qualification Round (After)

■問題A
2進カウンタをK回進めたとき,下位Nビットが全て1なら"ON",そうでないなら"OFF"を出力せよ.

□解法B
ビット演算でクールにキメたかったのですが,あまり自信が無かったため,Kを2進文字列に直した後,下位Nビットが全て1であるか調べました.
  1. import java.io.*;  
  2. public class A {  
  3.  public void a() throws Exception{  
  4.   BufferedReader br=new BufferedReader(new FileReader("C:\\A-large.in"));  
  5.   BufferedWriter bw=new BufferedWriter(new FileWriter("C:\\A-large.out"));  
  6.   int T=Integer.parseInt(br.readLine());  
  7.   for(int i=0;i<T;i++){  
  8.    String[] s=br.readLine().split(" ");  
  9.    int N=Integer.parseInt(s[0]);  
  10.    int K=Integer.parseInt(s[1]);  
  11.    String t=toBS(K);  
  12.    boolean f=true;  
  13.    for(int j=t.length()-N;j<t.length();j++){  
  14.     if(j<0||t.charAt(j)!='1'){  
  15.      f=false;  
  16.      break;  
  17.     }  
  18.    }  
  19.    String ans="Case #"+(i+1)+": "+(f?"ON":"OFF");  
  20.    bw.write(ans);  
  21.    bw.newLine();  
  22.   }  
  23.   bw.close();  
  24.  }  
  25.  String toBS(int n){  
  26.   if(n==0)  
  27.    return "0";  
  28.   String s="";  
  29.   while(n!=0){  
  30.    s=n%2+s;  
  31.    n/=2;  
  32.   }  
  33.   return s;  
  34.  }  
  35. }  

■問題B
長い文章でしたが,問題自体は↓.
maxy gcd(t1+y, t2+y, …, tN+y)となる最小のyを求めよ.

□解法B
まず,gcd(t1+y, t2+y, …, tN+y)=mとします.
このとき,
m|ti+y (1≦i≦N)
であるため,
m|(ti+y)-(tj+y) (1≦i, j≦N)
よって,
m|ti-tj (1≦i, j≦N)
ここで,
gcd1≦i, j≦N(ti-tj)=n
とすれば,n=m(のはずです…).
あとは,m|t1+yとなるようにyを求めて((m-t1)%mを計算する)終わり.
  1. import java.io.*;  
  2. import java.math.*;  
  3. import java.util.*;  
  4.   
  5. public class B {  
  6.  BigInteger calcY(int N,BigInteger[] t){  
  7.   Arrays.sort(t);  
  8.   
  9.   LinkedList<BigInteger> list=new LinkedList<BigInteger>();  
  10.   for(int j=0;j<N-1;j++)  
  11.    for(int i=j+1;i<N;i++)  
  12.     list.add(t[j].subtract(t[i]));  
  13.   BigInteger gcd=list.get(0);  
  14.   for(BigInteger bi:list)  
  15.    gcd=bi.gcd(gcd);  
  16.    return gcd.subtract(t[0]).mod(gcd);  
  17.  }  
  18.    
  19.  public void b() throws Exception{  
  20.   BufferedReader br=new BufferedReader(new FileReader("C:\\B-large.in"));  
  21.   BufferedWriter bw=new BufferedWriter(new FileWriter("C:\\B-large.out"));  
  22.   int C=Integer.parseInt(br.readLine());  
  23.   for(int i=0;i<C;i++){  
  24.    String[] s=br.readLine().split(" ");  
  25.    int N=Integer.parseInt(s[0]);  
  26.    BigInteger[] t=new BigInteger[N];  
  27.    for(int j=0;j<N;j++)  
  28.     t[j]=new BigInteger(s[j+1]);  
  29.    BigInteger y=calcY(N,t);  
  30.    String ans="Case #"+(i+1)+": "+y;  
  31.    bw.write(ans);  
  32.    bw.newLine();  
  33.   }  
  34.   bw.close();  
  35.  }  
  36. }  

■問題C
1人以上の客から構成されるグループがNグループある.1Euro/人とすると,k人乗りのローラーコースターをR回走らせた時,いくら稼げるか.

R=4,k=6,N=4として,グループ毎の人数を[1,4,2,1]と表すと,以下のようになります.

回数乗っているグループ待っているグループ儲け
1[1, 4][2, 1]5
2[2, 1, 1][4]4
3[4, 2][1, 1]6
4[1, 1 ,4][2]6

□解法C
R>Nであれば,必ず,以前走らせた時と同じパターンが出てくるので,それを記憶しておき…としたのですが,コーディングをミスした模様.largeでエラー連発でした.

■結果
ABC
small
large×
point333310

76Point,2318位.

とりあえずは予選通過,ということで.

0 件のコメント: