Codechefに初参加したので、その参戦記です。
開始後、とりあえず、一番おいしそうな名前の(本当にそういう理由です)"Popular Rice Recipe"に挑戦します。難しくありません、昨日のTopcoderでも似たような問題がありましたが、今度はCですのでもっと楽です。14minでaccept。
ですが、これ以降が情けないのです。
次に人数の多い、"Socializing Game around Pizza"に挑戦しますが、なかなかうまくいきません。幾つか予想をたてて、証明も考えました。
予想1:Bが勝つものに2,3を足したものはAが勝てる(これは理由があって、問題文から、Aは「Bが勝つ」形にピザを変形できます。Bが勝つ=その段階での後手が勝つ、なのでこの場合Aが勝てます。)
予想2:偶数ならAが勝つ(線対称に切って、対称性を崩さないようにすれば勝てます)。
まではうまく行ったのですが、ここから「4で割って1余るときだけBがかつ」としたのは勇み足でした。42minでWrong Answer。いろいろ考えるも、奇数の場合の処理が思いつかず、お手上げです。
仕方がないので戻ってみると、"Distribute idlis Equally"のほうが増えていたので、それを解きます。マージソートで実装して、次いでストランドソートを使いましたが、どちらもTLE。どうしたらよかったのでしょうか。
この段階で諦めて、1/5でした。コンペティションサイトはこちら。
恒例のソース公開です。
"Popular Rice Recipe"
極めて単純に組みました。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct{
char name[21];
char sign;
} user;
int main(void){
int t,n,point;
int i,j,k,flg,usercount;
user *users;
char names[21],signs;
scanf("%d",&t);
for(i=0;i<t;i++){
scanf("%d",&n);
users=(user *)calloc(n,sizeof(user));
usercount=0;
for(j=0;j<n;j++){
scanf("%s %c",names,&signs);
flg=0;
for(k=0;k<usercount;k++){
if(strcmp((users+k)->name,names)==0){
flg=1;
(users+k)->sign=signs;
break;
}
}
if(flg==0){
(users+usercount)->sign=signs;
strcpy((users+usercount)->name,names);
usercount++;
}
}
point=0;
for(j=0;j<usercount;j++){
if((users+j)->sign=='+') point++;
else if((users+j)->sign=='-') point--;
}
printf("%d\n",point);
}
free(users);
return 0;
}
"Socializing Game around Pizza"
先の「間違った予想」版です。
#include<stdio.h>
int main(void){
int n,in,i;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d",&in);
if(in%4==1) puts("Bhima");
else puts("Arjuna");
}
return 0;
}
"Distribute idlis Equally"
TLEなので解答は多分あっているのでしょう。いかほど遅いのでしょうか?
#include<stdio.h>
#include<stdlib.h>
#define SIZE 3000
void merge(int a[], int asize, int b[], int bsize, int c[], int csize);
void strandsort(int data[], int num);
int main(void){
int t,n,idils[SIZE],i,j,k;
int sum,count,tmp1,tmp2,flg;
scanf("%d",&t);
for(i=0;i<t;i++){
scanf("%d",&n);
sum=0;
for(j=0;j<n;j++){
scanf("%d",idils+j);
sum+=*(idils+j);
}
if(sum%n!=0){
puts("-1");
continue;
}
sum/=n;
strandsort(idils,n);
count=0;
while(idils[0]!=sum){
count++;
k=(idils[n-1]-idils[0]+1)/2;
idils[n-1]-=k;
idils[0]+=k;
strandsort(idils,n);
}
printf("%d\n",count);
}
return 0;
}
void merge(int a[], int asize, int b[], int bsize, int c[], int csize) {
int i, j = 0, k = 0;
for (i = 0; i < csize; i++) {
if (j >= asize) {
c[i] = b[k];
k++;
continue;
}else if (k >= bsize) {
c[i] = a[j];
j++;
continue;
}
if (a[j] > b[k]) {
c[i] = b[k];
k++;
}else{
c[i] = a[j];
j++;
}
}
}
void strandsort(int data[], int num) {
int sub[SIZE],res[SIZE],sub_ct=0,res_ct=0,tmp[SIZE];
int i,j,k;
while(res_ct<num){
for(i=0;i<num;i++){
if(data[i]==-1) continue;
if(sub_ct==0){
sub[0]=data[i];
data[i]=-1;
sub_ct++;
}else if(sub[sub_ct-1]<=data[i]){
sub[sub_ct]=data[i];
data[i]=-1;
sub_ct++;
}
}
if(res_ct==0){
res_ct+=sub_ct;
for(i=0;i<sub_ct;i++) res[i]=sub[i];
sub_ct=0;
}else{
merge(sub,sub_ct,res,res_ct,tmp,sub_ct+res_ct);
res_ct+=sub_ct;
for(i=0;i<res_ct;i++) res[i]=tmp[i];
sub_ct=0;
}
}
for(i=0;i<num;i++) data[i]=res[i];
return;
}
0 件のコメント:
コメントを投稿