CodeChef August Cook-off 2011(8/22 1:00~3:30)
■Open the Dragon Scroll
問題
A,B,Nが与えられる.(2進数で)A,BのビットをNビットに収まる範囲で自由に並び替える.
A xor B = Cの最大値を求めよ.
解法
A,Bにおける1のビットの数を|A|,|B|とする.1.|A|+|B|≦N
この時は,以下のようにビットを並び替えれば最大値になる.A→11…1100…0000…00
B→00…0011…1100…00
C→11…1111…1100…00
(1が|A|+|B|個,0がN-(|A|+|B|)個)
2.|A|+|B|>N
xorをとると,どうしてもどこかでAの1とBの1が相殺して0になってしまう.そのため,ビットを下のように並びかえる.
A→11…1100…0011…11
B→00…0011…1111‥11
この時,1 xor 1 = 0で相殺されてしまう1(右端の1のこと)の個数をXとすれば,
|A|+|B|-X=N
∴X=|A|+|B|-N
C→11…1111…1100…00
(1が2|N|-(|A|+|B|)個,0が|A|+|B|-N個)
- import java.util.*;
- import java.lang.*;
- import java.math.*;
- import java.io.*;
- import static java.lang.Math.*;
- import static java.util.Arrays.*;
- public class Main{
- Scanner sc=new Scanner(System.in);
- int INF=1<<28;
- double EPS=1e-9;
- int t, n, a, b;
- void run(){
- t=sc.nextInt();
- for(int i=0; i<t; i++){
- n=sc.nextInt();
- a=sc.nextInt();
- b=sc.nextInt();
- solve();
- }
- }
- void solve(){
- int ans=0;
- int bitA=Integer.bitCount(a);
- int bitB=Integer.bitCount(b);
- if(bitA+bitB<=n){
- for(int i=0; i<n; i++){
- ans<<=1;
- if(i<bitA+bitB){
- ans++;
- }
- }
- }else{
- for(int i=0; i<n; i++){
- ans<<=1;
- if(i<2*n-(bitA+bitB)){
- ans++;
- }
- }
- }
- println(ans+"");
- }
- void println(String s){
- System.out.println(s);
- }
- void print(String s){
- System.out.print(s);
- }
- void debug(Object... os){
- System.err.println(Arrays.deepToString(os));
- }
- public static void main(String[] args){
- new Main().run();
- }
- }
■Vote for the Noodle Soup
問題
ある投票システムがある.投票する際のスコアは+1/-1で,一度投票したら無効には出来ない.
スコアを見るためには,上記のスコアで投票する必要がある.
Poは,(+1/-1に)複数回投票し,スコアを記録した.
得られたスコアから,(Poを除いた)総投票者の最小数を求めよ.
解法
得られたスコアをscore[i]と表す.Poが入れたポイント(vote[i]とする)は計算の邪魔なので,score[i]から予め引いておく.
score[0]~score[n-1]まで逐一見ていく.
i番目まで見たときの投票者数の最小値をnUsers[i]とする.
明らかなのは,
nUsers[0]=0
nUsers[i+1]=max(nUsers[i], |score[i+1]|)
ということ.投票者数は,最低でもスコアの絶対値だけ必要.
次に,nUsers[i]+score[i+1]が奇数だった場合は,
nUsers[i+1]=nUsers[i]+1
とする必要がある.何故なら,
nUsers[i]が偶数/奇数⇔score[i]が偶数/奇数
だから.そして,投票者数は減らないから,+1する.
- import java.util.*;
- import java.lang.*;
- import java.math.*;
- import java.io.*;
- import static java.lang.Math.*;
- import static java.util.Arrays.*;
- public class Main{
- Scanner sc=new Scanner(System.in);
- int INF=1<<28;
- double EPS=1e-9;
- int n;
- int[] vote, ps;
- void run(){
- for(;;){
- n=sc.nextInt();
- if(n==0){
- break;
- }
- vote=new int[n];
- ps=new int[n];
- for(int i=0; i<n; i++){
- vote[i]=sc.next().equals("P")?+1:-1;
- ps[i]=sc.nextInt()-vote[i];
- }
- solve();
- }
- }
- void solve(){
- int min=0;
- for(int i=0; i<n; i++){
- if(abs(ps[i]+min)%2==1){
- min++;
- }
- min=max(min, abs(ps[i]));
- }
- println(min+"");
- }
- void println(String s){
- System.out.println(s);
- }
- void print(String s){
- System.out.print(s);
- }
- void debug(Object... os){
- System.err.println(Arrays.deepToString(os));
- }
- public static void main(String[] args){
- new Main().run();
- }
- }
■Result
o-o--実に不本意な結果….
0 件のコメント:
コメントを投稿