P1708 题解
观察到值域
打表的思路也很简单:使用一个三重循环,最外层为 ans
中,最后输出到文件,复制进代码中,打表完成。
完整代码如下:
//by Cuset_Nekomusume 20240310 #include <bits/stdc++.h> #define int long long using namespace std; typedef long long ll; typedef long double ld; //an数组为打好的表,ans为打表时的暂存数组。 int ans[8]; int an[7][101] = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9}, {0, 2, 5, 9, 14, 20, 27, 35, 44, 54, 63, 71, 78, 84, 89, 93, 96, 98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}, {0, 3, 9, 19, 34, 55, 83, 119, 164, 219, 282, 351, 424, 499, 574, 647, 716, 779, 834, 879, 915, 943, 964, 979, 989, 995, 998, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999}, {0, 4, 14, 34, 69, 125, 209, 329, 494, 714, 996, 1344, 1759, 2239, 2779, 3371, 4004, 4664, 5334, 5994, 6627, 7219, 7759, 8239, 8654, 9002, 9284, 9504, 9669, 9789, 9873, 9929, 9964, 9984, 9994, 9998, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999}, {0, 5, 20, 55, 125, 251, 461, 791, 1286, 2001, 2997, 4337, 6082, 8287, 10997, 14243, 18038, 22373, 27213, 32493, 38124, 43999, 49999, 55999, 61874, 67505, 72785, 77625, 81960, 85755, 89001, 91711, 93916, 95661, 97001, 97997, 98712, 99207, 99537, 99747, 99873, 99943, 99978, 99993, 99998, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999, 99999}, {0, 6, 27, 83, 209, 461, 923, 1715, 3002, 5004, 8001, 12333, 18395, 26627, 37499, 51491, 69068, 90650, 116577, 147069, 182196, 221858, 265775, 313487, 364364, 417626, 472373, 527625, 582372, 635634, 686511, 734223, 778140, 817802, 852929, 883421, 909348, 930930, 948507, 962499, 973371, 981603, 987665, 991997, 994994, 996996, 998283, 999075, 999537, 999789, 999915, 999971, 999992, 999998, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999}, {0, 7, 35, 119, 329, 791, 1715, 3431, 6434, 11439, 19440, 31767, 50135, 76679, 113969, 164999, 233144, 322079, 435654, 577719, 751914, 961439, 1208819, 1495679, 1822544, 2188679, 2591984, 3028959, 3494754, 3983319, 4487634, 4999999, 5512364, 6016679, 6505244, 6971039, 7408014, 7811319, 8177454, 8504319, 8791179, 9038559, 9248084, 9422279, 9564344, 9677919, 9766854, 9834999, 9886029, 9923319, 9949863, 9968231, 9980558, 9988559, 9993564, 9996567, 9998283, 9999207, 9999669, 9999879, 9999963, 9999991, 9999998, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999, 9999999}}; //get1~7为获取一个数每一位的函数,很简单,对吧awa inline int get1(int x) { return x % 10; } inline int get2(int x) { return x / 10 % 10; } inline int get3(int x) { return x / 100 % 10; } inline int get4(int x) { return x / 1000 % 10; } inline int get5(int x) { return x / 10000 % 10; } inline int get6(int x) { return x / 100000 % 10; } inline int get7(int x) { return x / 1000000 % 10; } //init1~7为打表的暴力循环函数,比较冗长,不过好理解 inline void init1(int k) { for (int i = 1; i <= 9; i++) { if (i <= k) ans[1]++; } } inline void init2(int k) { for (int i = 1; i <= 9; i++) { if (i <= k) ans[1]++; } for (int i = 10; i <= 99; i++) { if (get1(i) + get2(i) <= k) ans[2]++; } ans[2] += ans[1]; //此处循环仅处理了对应位数的答案,所以要求一遍前缀和,下同。 } inline void init3(int k) { for (int i = 1; i <= 9; i++) { if (i <= k) ans[1]++; } for (int i = 10; i <= 99; i++) { if (get1(i) + get2(i) <= k) ans[2]++; } ans[2] += ans[1]; for (int i = 100; i <= 999; i++) { if (get1(i) + get2(i) + get3(i) <= k) ans[3]++; } ans[3] += ans[2]; } inline void init4(int k) { for (int i = 1; i <= 9; i++) { if (i <= k) ans[1]++; } for (int i = 10; i <= 99; i++) { if (get1(i) + get2(i) <= k) ans[2]++; } ans[2] += ans[1]; for (int i = 100; i <= 999; i++) { if (get1(i) + get2(i) + get3(i) <= k) ans[3]++; } ans[3] += ans[2]; for (int i = 1000; i <= 9999; i++) { if (get1(i) + get2(i) + get3(i) + get4(i) <= k) ans[4]++; } ans[4] += ans[3]; } inline void init5(int k) { for (int i = 1; i <= 9; i++) { if (i <= k) ans[1]++; } for (int i = 10; i <= 99; i++) { if (get1(i) + get2(i) <= k) ans[2]++; } ans[2] += ans[1]; for (int i = 100; i <= 999; i++) { if (get1(i) + get2(i) + get3(i) <= k) ans[3]++; } ans[3] += ans[2]; for (int i = 1000; i <= 9999; i++) { if (get1(i) + get2(i) + get3(i) + get4(i) <= k) ans[4]++; } ans[4] += ans[3]; for (int i = 10000; i <= 99999; i++) { if (get1(i) + get2(i) + get3(i) + get4(i) + get5(i) <= k) ans[5]++; } ans[5] += ans[4]; } inline void init6(int k) { for (int i = 1; i <= 9; i++) { if (i <= k) ans[1]++; } for (int i = 10; i <= 99; i++) { if (get1(i) + get2(i) <= k) ans[2]++; } ans[2] += ans[1]; for (int i = 100; i <= 999; i++) { if (get1(i) + get2(i) + get3(i) <= k) ans[3]++; } ans[3] += ans[2]; for (int i = 1000; i <= 9999; i++) { if (get1(i) + get2(i) + get3(i) + get4(i) <= k) ans[4]++; } ans[4] += ans[3]; for (int i = 10000; i <= 99999; i++) { if (get1(i) + get2(i) + get3(i) + get4(i) + get5(i) <= k) ans[5]++; } ans[5] += ans[4]; for (int i = 100000; i <= 999999; i++) { if (get1(i) + get2(i) + get3(i) + get4(i) + get5(i) + get6(i) <= k) ans[6]++; } ans[6] += ans[5]; } inline void init7(int k) { for (int i = 1; i <= 9; i++) { if (i <= k) ans[1]++; } for (int i = 10; i <= 99; i++) { if (get1(i) + get2(i) <= k) ans[2]++; } ans[2] += ans[1]; for (int i = 100; i <= 999; i++) { if (get1(i) + get2(i) + get3(i) <= k) ans[3]++; } ans[3] += ans[2]; for (int i = 1000; i <= 9999; i++) { if (get1(i) + get2(i) + get3(i) + get4(i) <= k) ans[4]++; } ans[4] += ans[3]; for (int i = 10000; i <= 99999; i++) { if (get1(i) + get2(i) + get3(i) + get4(i) + get5(i) <= k) ans[5]++; } ans[5] += ans[4]; for (int i = 100000; i <= 999999; i++) { if (get1(i) + get2(i) + get3(i) + get4(i) + get5(i) + get6(i) <= k) ans[6]++; } ans[6] += ans[5]; for (int i = 1000000; i <= 9999999; i++) { if (get1(i) + get2(i) + get3(i) + get4(i) + get5(i) + get6(i) + get7(i) <= k) ans[7]++; } ans[7] += ans[6]; } signed main() { // freopen("t.out", "w", stdout); // for (int i = 1; i <= 7; i++) { // for (int j = 1; j <= 100; j++) { // memset(ans, 0, sizeof(ans)); // if (i == 1) init1(j); // if (i == 2) init2(j); // if (i == 3) init3(j); // if (i == 4) init4(j); // if (i == 5) init5(j); // if (i == 6) init6(j); // if (i == 7) init7(j); // printf("%lld, ", ans[i]); // } // printf("\n"); // } int t; cin >> t; int n, k; for (int i = 1; i <= t; i++) { cin >> n >> k; printf("%lld\n", an[n - 1][k]); } return 0; }
代码中,main
函数注释掉的一段为打表部分,未注释掉的为输出部分。打表部分用时 很快的。因此,在比赛时如果题目值域小,打表也不失为一种好的方式。
完结撒花awa~
本文作者:CusetVoidAldehyde
本文链接:https://www.cnblogs.com/CusetVoidAldehyde/p/18269098
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步