2011年7月4日月曜日

TopCoder SRM 511

TopCoder SRM 511(7/3 1:00~3:00)

YellowCoderとしては初のSRM.

■Zoo(Easy)

・問題

うさぎと猫がN匹いる.きつねは,うさぎと猫の区別が分からない.
そこで,N匹のそれぞれに「自分と同じ種類でかつ自分より背の高い動物は何匹いますか?」と尋ねた.
この情報のみを用いて,N匹へのうさぎと猫の割り当て方の総数を求めよ.

・解法

N匹の答えをa[0],…,a[N-1]とし,
配列countを配列aに出てきた数字の個数とする.
例えば, a={0,1,0,1,2,3}
だったら,
count={2,2,1,1,0,0,…}
となる.
上の例では,一方が2匹,もう一方が4匹いると分かる.
まず,うさぎが2匹,猫が4匹とする.
このとき,a[i]が0または1のときに関しては,うさぎと猫をどのように割り当てても良い.
具体的には,
RRCC|CC
CCRR|CC
RCCR|CC
CRRC|CC
こんな感じ(22通り).
逆に,うさぎが4匹,猫が2匹としても,上と同じよう構成ができるので,
結局2*22=8通り.
これは,5匹と2匹,6匹と2匹,…でも変わらない.
そのため,N=m+nと分かれる場合,
m≠nならば,2*2min(m,n)通り,
m=nならば,2m通り.
  1. import java.util.*;  
  2. import java.lang.*;  
  3. import java.math.*;  
  4. import java.io.*;  
  5.   
  6. import static java.lang.Math.*;  
  7. import static java.util.Arrays.*;  
  8.   
  9. public class Zoo {  
  10.  // long INF=1L<<48;  
  11.  int INF=1<<28;  
  12.  double EPS=1e-9;  
  13.   
  14.  public long theCount(int[] a) {  
  15.   int n=a.length;  
  16.   int[] count=new int[n];  
  17.   for(int i:a){  
  18.    if(i>=n){  
  19.     return 0;  
  20.    }  
  21.    if(++count[i]>2){  
  22.     return 0;  
  23.    }  
  24.   }  
  25.   int p=0, q=0;  
  26.   int k=0;  
  27.   // debug(count);  
  28.   for(int i=n-1;i>=0;i--){  
  29.    if(count[i]==k+2){  
  30.     p=q=i+1;  
  31.    }  
  32.    else if(count[i]==k+1){  
  33.     if(k==0){  
  34.      p=i+1;  
  35.     }else if(k==1){  
  36.      q=i+1;  
  37.     }  
  38.    }  
  39.    else if(count[i]==k){  
  40.    }  
  41.    else{  
  42.     return 0;  
  43.    }  
  44.    k=count[i];  
  45.   }  
  46.   // debug(p,q);  
  47.   long ret=1;  
  48.   for(int i=0;i<min(p,q);i++){  
  49.    ret*=2;  
  50.   }  
  51.   return ret*(p!=q?2:1);  
  52.  }  
  53.   
  54.  void debug(Object...os){  
  55.   System.err.println(Arrays.deepToString(os));  
  56.  }  
  57.   
  58.  void print(String s){  
  59.   System.out.print(s);  
  60.  }  
  61.   
  62.  void println(String s){  
  63.   System.out.println(s);  
  64.  }  
  65. }  

■FiveHundredElevenAdd(Medium)

本番は解けませんでしたので,simezi_tanさんの記事を参照下さい.
SRM 511 Div1 Medium FiveHundredEleven - simezi_tanの日記
  1. import java.util.*;  
  2. import java.lang.*;  
  3. import java.math.*;  
  4. import java.io.*;  
  5.   
  6. import static java.lang.Math.*;  
  7. import static java.util.Arrays.*;  
  8.   
  9. public class FiveHundredEleven {  
  10.  // long INF=1L<<48;  
  11.  int INF=1<<28;  
  12.  double EPS=1e-9;  
  13.   
  14.  int[][] memo; // 0:win, 1:lose  
  15.  int[] cards;  
  16.  int n;  
  17.   
  18.  int rec(int step,int mem){  
  19.   if(memo[step][mem]>=0){  
  20.    return memo[step][mem];  
  21.   }  
  22.   if(mem==511){  
  23.    // former player loses.  
  24.    return memo[step][mem]=0;  
  25.   }  
  26.   if(step==n){  
  27.    // the player can't choose a card.  
  28.    return memo[step][mem]=1;  
  29.   }  
  30.   int not=0;  
  31.   for(int i=0;i<n;i++){  
  32.    if((mem|cards[i])==mem){  
  33.     not++;  
  34.    }  
  35.   }  
  36.   boolean win=false;  
  37.   // search : not-step cards that don't affect mem are not used  
  38.   if(not>step){  
  39.    win|=rec(step+1,mem)==1;  
  40.   }  
  41.   // search : cards that affect mem.  
  42.   for(int i=0;i<n;i++){  
  43.    if((mem|cards[i])!=mem){  
  44.     win|=rec(step+1,mem|cards[i])==1;  
  45.    }  
  46.   }  
  47.   return memo[step][mem]=win?0:1;  
  48.  }  
  49.   
  50.  public String theWinner(int[] cards) {  
  51.   this.cards=cards;  
  52.   n=cards.length;  
  53.   memo=new int[n+1][512];  
  54.   for(int i=0;i<n+1;i++){  
  55.    fill(memo[i],-1);  
  56.   }  
  57.   return rec(0,0)==0?"Fox Ciel":"Toastman";  
  58.  }  
  59.   
  60.  void debug(Object...os){  
  61.   System.err.println(Arrays.deepToString(os));  
  62.  }  
  63.   
  64.  void print(String s){  
  65.   System.out.print(s);  
  66.  }  
  67.   
  68.  void println(String s){  
  69.   System.out.println(s);  
  70.  }  
  71. }  

■Challenge Phase

撃墜無し.撃墜しようと準備していましたが,他の人のコードが中々読めませんでした.

■Result

o-- +0/-0
144.29pts. 491th

■Rating

1532 -> 1527
微減.次は,TCO Round3ですが,個人的には気楽に挑戦したいと思っています.

0 件のコメント: