質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

1778閲覧

サイコロをn回投げて出た目の総積がDの倍数となる確率は? C++

cbeginner

総合スコア7

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2018/05/23 09:17

編集2018/05/23 22:15

前提・実現したいこと

atcoderというプログラミングコンテストをオンラインで開催しているサイトに載っていたこの質問のタイトルにある問題について、自分のソースコードの間違いを指摘して頂けるとありがたいです。標準入力で整数値n(1<=n<=100),D(1<=D<=1e18)が与えられ、絶対誤差1e-6以下で正しい値を出力できれば正解となります。
↓こちらのリンクから問題の詳細が確認できます。
https://beta.atcoder.jp/contests/tdpc/tasks/tdpc_dice

発生している問題・エラーメッセージ

1つのテストケースにのみ正解できていません。(テストケースの中身は全て非公開になっています。)

該当のソースコード

c++

1#include <bits/stdc++.h> 2using namespace std; 3 4#define db double 5#define rep0(i,n) for(int i=0;i<n;i++) 6#define rep1(i,n) for(int i=1;i<=n;i++) 7#define repU(i,bottom,ceiling) for(int (i)=(bottom);(i)<=(ceiling);(i)++) 8#define repD(i,ceiling,bottom) for(int (i)=(ceiling);(i)>=(bottom);(i)--) 9#define V vector 10#define vi vector<int> 11#define pub(v,el) v.push_back(el) 12#define pob(v) v.pop_back 13#define ci(a) cin>>a 14#define lco(a) cout<<a<<endl 15#define co(a) cout<<a 16#define vco(v) rep0(i,v.size()){ co(v[i]<<' '); } co('\n') 17#define pii pair<int,int> 18#define mp(a,b) make_pair(a,b) 19#define fir first 20#define sec second 21 22typedef long long ll; 23 24const int dir[8][2]={{0,1},{1,0},{0,-1},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1}}; 25const int Inf=2e9+1e8; 26 27template <typename T,typename U> 28pair<T,U> operator+(const pair<T,U> & l,const pair<T,U> & r) { 29 return {l.fir+r.fir,l.sec+r.sec}; 30} 31 32template <typename T,typename U> 33pair<T,U> operator-(const pair<T,U> & l,const pair<T,U> & r) { 34 return {l.fir-r.fir,l.sec-r.sec}; 35} 36 37int order(ll n,int p){ 38 if((ll)n%p) return 0; 39 return 1+order(n/(ll)p,p); 40} 41 42int main(){ 43 int n,p[3]; 44 ll d; 45 ci(n>>d); 46 p[0]=order(d,2); 47 p[1]=order(d,3); 48 p[2]=order(d,5); 49 if(d/(1<<p[0])/pow(3,p[1])/pow(5,p[2])>1){ 50 lco('0'); 51 return 0; 52 } 53 V<V<V<V<db>>>> dp=V<V<V<V<db>>>>(n+1, V<V<V<db>>>(p[0]+1,V<V<db>>(p[1]+1,V<db>(1+p[2],0)))); 54 dp[0][0][0][0]=1; 55 repU(cnt,0,n){ 56 repU(a,0,p[0]){ 57 repU(b,0,p[1]){ 58 repU(c,0,p[2]){ 59 if(!cnt){ if(a||b||c){ dp[cnt][a][b][c]=0; } continue; } 60 dp[cnt][a][b][c]= (dp[cnt-1][a][b][c]+dp[cnt-1][max(0,a-1)][b][c]+dp[cnt-1][a][max(0,b-1)][c]+dp[cnt-1][a][b][max(0,c-1)]+dp[cnt-1][max(0,a-2)][b][c]+dp[cnt-1][max(a-1,0)][max(0,b-1)][c])/6; 61 } 62 } 63 } 64 } 65 printf("%.10f\n",dp[n][p[0]][p[1]][p[2]]); 66 return 0; 67} 68

試したこと

コーナーケースを念入りに確認したつもりです。

補足情報(FW/ツールのバージョンなど)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

okrt

2018/05/23 14:24

問題のアドレスは消さないほうが親切ですね
cbeginner

2018/05/23 22:12

iPadではリンクとして機能しておらずコピーも出来なかったため消してしまいました。貼り直しておきます。
mkgrei

2018/05/23 22:28

自前のマクロが激しすぎるせいでバグを誘発しやすい状況にあるように見えるのですが、あえて別言語のようにして回答者の方に見てもらいたいのですか?普通に書かれた方が回答を得やすいかと思われます。一応。
cbeginner

2018/05/23 22:38

意見ありがとうございます。僕はコーディングスキルが低く、今回のコードのように4次元vectorなどを用いる場合も少なくないため、その宣言等において自分に見やすくするというのが主な目的です。mkgreiさんの意見も踏まえ今後の投稿ではより読みやすいコードを付すことを心がけたいと思います。
guest

回答2

0

ベストアンサー

部分的に読んだだけですが、

if(d/(1<<p[0])/pow(3,p[1])/pow(5,p[2])>1)

は怪しいです。
例えば
99 1125899906842624
が入力された場合、Dは2の50乗なので99回の積がDの倍数になるパターンは多数存在するはずですが、このコードでは多くの環境で0になると思います。

投稿2018/05/23 14:22

okrt

総合スコア366

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cbeginner

2018/05/23 22:31

ありがとうございます。確かに(99,2^50)という入力に対しては0が出力されました。そこでorderの取り方を少し変更して上手く行きました。(https://beta.atcoder.jp/contests/tdpc/submissions/2552826) また、単に1,3,5をlong longへキャストしてから使用するように変更してもやはり成功しました。(https://beta.atcoder.jp/contests/tdpc/submissions/2552830) やはり元のコードの欠陥というのは、定数1,3,5がintとしてメモリ確保されていたために左シフト後の値、あるいはpowに入れた結果がオーバーフローしうる点だった、と結論づけてよいのでしょうか?
okrt

2018/05/24 12:47

そうですね。 シフトやpowの結果が32bitで扱える範囲を超える可能性があったのにintで演算してたから、intが32bitの環境では不正解になっていた ということで良いと思います。
guest

0

サンプルインプット2 6の結果がサンプルアウトプット0.416666667と異なります
すいません。絶対誤差による判定でしたね

投稿2018/05/23 13:27

編集2018/05/23 13:29
asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cbeginner

2018/05/23 13:32

そのサンプルに対してはコードテストでは絶対誤差1e-6の範囲で出力できています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問