結果

問題 No.362 門松ナンバー
ユーザー 37zigen37zigen
提出日時 2016-05-26 23:51:48
言語 Java21
(openjdk 21)
結果
AC  
実行時間 163 ms / 3,000 ms
コード長 2,211 bytes
コンパイル時間 2,340 ms
コンパイル使用メモリ 78,872 KB
実行使用メモリ 42,876 KB
最終ジャッジ日時 2024-10-07 16:22:54
合計ジャッジ時間 6,268 ms
ジャッジサーバーID
(参考情報)
judge5 / judge4
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 163 ms
42,704 KB
testcase_01 AC 151 ms
42,840 KB
testcase_02 AC 144 ms
42,192 KB
testcase_03 AC 150 ms
42,604 KB
testcase_04 AC 132 ms
42,548 KB
testcase_05 AC 143 ms
42,624 KB
testcase_06 AC 140 ms
42,412 KB
testcase_07 AC 152 ms
42,540 KB
testcase_08 AC 144 ms
42,180 KB
testcase_09 AC 152 ms
42,576 KB
testcase_10 AC 139 ms
42,328 KB
testcase_11 AC 134 ms
42,040 KB
testcase_12 AC 146 ms
42,468 KB
testcase_13 AC 148 ms
42,432 KB
testcase_14 AC 151 ms
42,712 KB
testcase_15 AC 144 ms
42,524 KB
testcase_16 AC 153 ms
42,584 KB
testcase_17 AC 135 ms
42,280 KB
testcase_18 AC 135 ms
42,516 KB
testcase_19 AC 151 ms
42,432 KB
testcase_20 AC 153 ms
42,844 KB
testcase_21 AC 150 ms
42,876 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