1 条题解
-
0
自动搬运
来自洛谷,原作者为

stone_juice石汁
敲稀有滴物种石汁qaq搬运于
2025-08-24 21:22:26,当前版本为作者最后更新于2019-05-26 20:13:07,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
咱不谈什么高级算法,什么高深模拟,甚至转化进制都不需要。
并且,算法复杂度最高仅为
更加NB的是,main里的代码仅仅4行!
那么你可能要问我是什么代码这么NB。
答案就是:打表无敌!!!!
#include<bits/stdc++.h> using namespace std; int num[300]={0,1,2,3,4,5,6,7,8,9,10,15,16, 17,18,20,21,24,26,27,28,31, 33,36,40,45,46,50,51,52,55, 57,63,65,67,73,78,80,82,85, 88,91,92,93,98,99,100,104,105,107, 109,111,114,119,121,127,129,130,135,141, 142,150,151,154,160,164,170,171,173,178, 182,185,186,191,195,200,203,209,212,215, 219,227,235,242,246,252,255,257,264,273, 282,292,300,313,316,325,328,333,341,342, 343,357,364,365,373,381,393,400,414,427, 434,438,446,455,464,471,484,495,511,513, 546,555,560,564,585,624,626,644,646,651, 656,666,676,692,693,701,717,728,730,757, 771,777,787,819,820,856,868,910,939,975, 1023,1025,1066,1105,1221,1285,1312,1365,1432,1441, 1460,1539,1550,1640,1667,1755,1885,2000,2188,2268, 2293,2550,2565,2709,2730,2910,2920,2925,2997,3069, 3074,3075,3280,3315,3550,3591,3640,3663,3735,3740, 3855,3951,3999,4095,4097,4161,4225,4257,4289,4369, 4433,4593,4617,4681,5001,5049,5125,5189,5397,5461, 5740,5840,5854,6148,6200,6560,6562,6643,6697,6724, 6761,6825,6886,6889,6953,7300,7373,7381,7409,7447, 7462,7517,7667,7703,7777,7801,7997,8038,8119,8194, 8200,8258,8281,8322,8386,8578,8778,8802,9009,9103, 9201,9222,9490,9958,10252,10308,10658,10794,10858,10922, 10986,11253,11314,11757,11898,11950,12291,12355,12419,12483, 12547,12654,12691,13107,13124,13131,13205,13286,13299,13331}; int n,s,g; int main() { cin>>n>>s; for(g=1;num[g]<=s;g++); for(int i=0;i<n;i++)cout<<num[g+i]<<endl; return 0; }你要是看这个代码还不会,算我输。
当然,你可能会问,这个表是从哪里来的?
答:我会手算!答:我会写代码!
那么怎么写这个代码呢?
注意:下面要开始介绍打表的技巧,这些技巧可能会在比赛中用到
这些技巧仅适用于较难题
以及懒得写代码。实乃骗分好法。-
第一步
看题目,我们要求的是满足至少两个进制的回文数对吧。
那么我们先新开一个源码求每个进制下的回文数。
稍微思考一下,我们可以把回文数看做一个数正着输一遍,在倒着输一遍。(如果是奇数位中间的数只输1次) 那么我们的第一份源码就出来了。
我们可以用for套for套for....这个代码求每个进制下的回文数,听起来不难是吧?>.<
**由于是不同进制,所以我们要加上限制条件。即每一位枚举不能大于,为进制数。**然后我们就可以愉快的输出。(记得用!)
下面展示了一个求4进制7,8位回文数的过程。当然这个代码可以运行9次。只需要把限制条件4改为2-10中的另一个数再运行就可以了。要求其他位数的回文数只需要增减for循环个数以及cout个数就可以了。
#include<bits/stdc++.h> using namespace std; int main() { for(int a=1;a<4;a++) for(int b=1;b<4;b++) for(int c=1;c<4;c++) for(int d=1;d<4;d++)//你要是够莽,可以开更多for { cout<<a<<b<<c<<d<<c<<b<<a; cout<<a<<b<<c<<d<<d<<c<<b<<a; } }当然听起来好像是很麻烦,但是做起来的效率其实蛮高了。如果你还是嫌麻烦,你可以写个递归,用改变量的方式替代改for于cout。
好了,我们得到了各个进制下的回文数。
(什么!你把数据丢了?我叫过你用吧?)
-
第二步:
我们现在需要把你得到各个进制下的回文数全部转化为10进制。
这个实现很简单吧。那就直接上代码了!
记住要加!别看我没加!
我懒#include<bits/stdc++.h> using namespace std; int n,k,ans;//其中,k代表进制。可以自行修改 int main() { while(cin>>n) { for(int i=0;n;i++)//其中i为进制位数,为累乘服务 { int tmp=n%10;//取最后一位 else for(int j=1;j<=i;j++)tmp*=k; ans+=tmp; n/=10;//丢最后一位 } cout<<ans<<" "; } }-
第三步
现在你得到的回文数全是10进制了。但是题目要求必须同时满足两种进制的回文数才算。
我们怎么做呢?
非常简单!你刚刚得到了9个文件对吧?他们记录了各个进制的回文数,并且全部转化为了10进制。
那么就上黑科技:Ctrl+C and Ctrl+V
简而言之,就是把所有的数据贴在一个文件里。
然后你就可以很快乐的用一个判重代码来输出那些出现次数多余2的数字。
记住要!!(话说这是第几回提醒了...)
到此为止!你就得到了一个表!
是不是被我的骗分方法感动了总结
虽说打表暴力无情,但是其实打表也有他独特的方法。如果你能在适当时间进行打表,那么你总能占到一些便宜。上面那个题不是很难,可能还没到打一个表的地步。但是我这里着重展示了打表的方法。希望对各位OIer有帮助!
-
- 1
信息
- ID
- 208
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 2
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者