还是教练强啊,这个写法可以推广到很广哎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 }