問題はこちら
No.211 素数サイコロと合成数サイコロ (1) - yukicoder
2重ループで全探索するだけ
int main(){ int a[]={2,3,5,7,11,13},b[]={4,6,8,9,10,12},i,j,n=0,k; scanf("%d",&k); for(i=0;i<6;i++)for(j=0;j<6;j++)if(k==a[i]*b[j])n++; printf("%.12f",n/36.0); //出力形式を指定しないとデフォルトだと6桁くらいだから誤差でWAになる return 0; }
ところで、例えば素数ダイスの出目を1つ決めた時、積がKになるような合成数ダイスの出目は高々1個なので次のような書き換えができそう
main(){
int a[]={2,3,5,7,11,13},b[]={4,6,8,9,10,12},i,j,n=0,k;
scanf("%d",&k);
for(i=0;i<6;i++)if(k%a[i]==0&&/* k/a[i]がbに含まれるか? */)n++;
printf("%.12f",n/36.0);
return 0;
}
「k/a[i]がbに含まれるか」を調べるためにbはbitで保存する。1011101010000bを使えば
main(){
int a[]={2,3,5,7,11,13},b=5968,i,n=0,k;
scanf("%d",&k);
for(i=0;i<6;i++)if(k%a[i]==0&&k/a[i]<15&&b&1<<k/a[i])n++;
//32以上shiftした時の動作は未定義なのでそれを回避
printf("%.12f",n/36.0);
return 0;
}
と書ける。(ここではx<<33はx<<1と同じ挙動をするらしく、k/a[i]が32以上の時にはバグる)
というかだったらaの方もいらないんじゃ?
main(){
int a=10412,b=5968,i,j,n=0,k;
scanf("%d",&k);
for(i=1;i<14;i++)if(a&1<<i&&k%i==0&&k/i<15&&b&1<<k/i)n++;
printf("%.12f",n/36.0);
return 0;
}
ということでこれをぎゅっとして
s,n;
main(i){
for(scanf("%d",&s);i<15;)n+=10412>>i&s%i<1&s/i<15&5968>>s/i++;
s=!printf("%.12f",n/36.);
}
100B