結果

問題 No.362 門松ナンバー
ユーザー 37zigen37zigen
提出日時 2016-05-26 23:51:48
言語 Java21
(openjdk 21)
結果
AC  
実行時間 178 ms / 3,000 ms
コード長 2,211 bytes
コンパイル時間 2,480 ms
コンパイル使用メモリ 79,512 KB
実行使用メモリ 45,428 KB
最終ジャッジ日時 2024-04-16 17:42:21
合計ジャッジ時間 7,189 ms
ジャッジサーバーID
(参考情報)
judge2 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 171 ms
42,580 KB
testcase_01 AC 175 ms
42,656 KB
testcase_02 AC 172 ms
42,596 KB
testcase_03 AC 169 ms
42,676 KB
testcase_04 AC 174 ms
45,428 KB
testcase_05 AC 173 ms
42,556 KB
testcase_06 AC 170 ms
42,892 KB
testcase_07 AC 157 ms
42,308 KB
testcase_08 AC 170 ms
42,736 KB
testcase_09 AC 171 ms
42,604 KB
testcase_10 AC 172 ms
42,704 KB
testcase_11 AC 172 ms
42,596 KB
testcase_12 AC 175 ms
42,696 KB
testcase_13 AC 173 ms
42,828 KB
testcase_14 AC 173 ms
42,752 KB
testcase_15 AC 171 ms
42,852 KB
testcase_16 AC 170 ms
42,932 KB
testcase_17 AC 173 ms
42,824 KB
testcase_18 AC 178 ms
42,764 KB
testcase_19 AC 171 ms
42,740 KB
testcase_20 AC 171 ms
42,564 KB
testcase_21 AC 167 ms
42,716 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

package yukicoder;
import java.util.Scanner;
public class Main{
	public static void main(String[] args){
		new Main().solve();
	}
	void solve(){
		Scanner sc=new Scanner(System.in);
		int t=sc.nextInt();
		/*
		 *dp[一番左の桁の数][左から一つ右にずれた桁の数][桁数]=門松数の数
		 *leading 0を許す。
		 */
		long[][][] dp=new long[10][10][101];
		for(int i=0;i<10;i++){
			for(int j=0;j<10;j++){
				if(i==j)continue;
				dp[i][j][2]++;
			}
		}

		for(int digit=3;digit<20;digit++){
			for(int i=0;i<10;i++){
				for(int j=0;j<10;j++){
					for(int k=0;k<10;k++){
						if(isKadomatsu(i,j,k)){
							dp[i][j][digit]+=dp[j][k][digit-1];
						}
					}
				}
			}
		}
		//sum[i]:ちょうどi桁の門松数の数
		//leading 0を許さない
		long[] sum=new long[30];
		for(int digit=3;digit<30;digit++){
			for(int i=1;i<10;i++){
				for(int j=0;j<10;j++){
					sum[digit]+=dp[i][j][digit];
				}
			}
		}
		for(int rep=0;rep<t;rep++){
			long k=sc.nextLong();
			int d=3;
			//k番目の門松数はd桁の数
			long s=0;
			for(;;d++){
				s+=sum[d];
				if(s>=k){
					break;
				}
			}
			String ans="";
			long now=k;
			for(int i=d-1;i>=3;i--){
				now-=sum[i];
			}
			int pre1=-1;
			int pre2=-1;
			//leading 0を許さない。
			//最初の2桁を確定させる。
			out:for(int i=1;i<10;i++){
				for(int j=0;j<10;j++){
					now-=dp[i][j][d];

					if(now<=0){
						now+=dp[i][j][d];
						ans+=String.valueOf(i)+String.valueOf(j);
						pre1=i;
						pre2=j;
						d-=1;
						break out;
					}
				}
			}
			out2:for(;d>=2;d--){
				if(d==2){
					for(int i=0;i<10;i++){
						if(isKadomatsu(pre1,pre2,i)){
							now--;
							if(now==0){
								ans+=String.valueOf(i);
								break out2;
							}
						}
					}
				}
				out3:for(int i=0;i<10;i++){
					if(isKadomatsu(pre1,pre2,i)){
						now-=dp[pre2][i][d];
						if(now<=0){
							now+=dp[pre2][i][d];
							ans+=String.valueOf(i);
							pre1=pre2;
							pre2=i;
							break out3;
						}
					}
				}
			}
			System.out.println(ans);
		}

	}
	boolean isKadomatsu(int x,int y,int z){
		if(x==y||y==z||z==x)return false;
		if(x<y&&y>z)return true;
		if(x>y&&y<z)return true;
		return false;
	}
}
0