POJ Apocalypse Someday

POJ3208

还是教练强啊,这个写法可以推广到很广哎qwq

Code:

 1 #include <cstdio>
 2 using namespace std;
 3 int T, n, m;
 4 int f[21][4];//f[i][j]表示从j状态(当前有几个连续的6)走i步到达目标状态(有连续3个6)所有方案数 
 5 int g[4][21];//g[i][j]表示当前已有i个连续的6,在后面添加j后到达哪个状态 
 6 int main () {
 7     for (int i = 0; i < 3; i++) {
 8         g[i][6] = i + 1;//后面添加6就会相应的到下一个状态 
 9     }
10     for (int i = 0; i <= 9; i++) {
11         g[3][i] = 3;//当前已经有3个连续的6之后,后面加什么都会回到当前状态 
12     }
13     f[0][3] = 1;//初始化 
14     for (int i = 1; i <= 10; i++) {//枚举所有步数,也就是多少位 
15         for (int j = 0; j <= 3; j++) {//连续几个6 
16             for (int k = 0; k <= 9; k++) {//添加哪个数字 
17                 f[i][j] += f[i - 1][g[j][k]];//状态转移 
18             }
19         }
20     }
21     scanf("%d", &T);
22     while (T--) {
23         scanf("%d", &n);
24         for (m = 1; m < 11 && f[m][0] < n; m++) {
25             //确定目标状态的位数 
26         }
27         int p = 0;
28         for (int i = m, j = 0; i; i--) {//倒叙循环枚举到了哪一位 
29             for (j = 0; j <= 9; j++) {//这一位添哪个数字 
30                 if (n > f[i - 1][g[p][j]]) {
31                     n -= f[i - 1][g[p][j]];//如果添上该数字后仍然不够n就减去 
32                 } else {
33                     break;
34                 }
35             }
36             printf("%d", j);//把添的这一位输出 
37             p = g[p][j];//添了数字后到达下一个状态 
38         }
39         puts("");
40     }
41     return 0;
42 }
View Code
原文地址:https://www.cnblogs.com/Sundial/p/11830569.html