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 件のコメント:
コメントを投稿