题目链接:https://www.vijos.org/p/1162
这题的解法我觉得可能是模拟吧,但是题的分类又是构造QAQ。。。。。
不是很懂,所以我们把这个方法叫做奇技淫巧吧
这题的暴力思路就是针对x到y这个范围里的每一个数进行判断,可以就输出
但是很容易看出,这个暴力会超时
所以就有了奇技淫巧
【思路】
我们预处理出范围内所有波浪数的波浪重数
这些波浪数我们可以主动去构造,这题中的波浪数其实拆开就是两个数字构成的,所有只需要枚举奇数位的i,和偶数位的j,i不能为0,然后最大为进制数-1
然后我们处理一下输入的范围x,y在p进制下的位数,并通过我们枚举的i,j和进制p构造位数在x,y之间的p进制数,接着把这个数转换成十进制,让这个波浪数的重数在十进制状态下+1,最后再十进制下枚举x,y之间的所有数,如果重数等于输入的s,就输出这个数
这个题的代码也不难,非常容易看懂滴

1 #include2 #include 首位不为0 31 for(int j=0;j3 #include 4 #include 5 #include 6 #include 7 #include 8 #define maxn 10000005 9 using namespace std; 10 11 int num[maxn],ja,jb,x,y,s; 12 13 int length(int n,int p){//数字n在p进制下的长度 14 int cnt=0; 15 while(n){ 16 n/=p;cnt++; 17 }return cnt; 18 } 19 20 int make(int a,int b,int len,int p){ 21 int now=0; 22 for(int i=1;i<=len;i++){ 23 if(i&1)now=now*p+a; 24 else now=now*p+b; 25 }return now;//转成10进制 26 } 27 28 void work(int p){ 29 int l=length(x,p),r=length(y,p); 30 for(int i=1;i //
){ 32 if(i!=j){//波浪数的条件 33 for(int k=l;k<=r;k++){ 34 int sum=make(i,j,k,p); 35 //构造波浪数并转换成十进制sum 36 if(sum>=x&&sum<=y)num[sum]++; 37 } 38 } 39 } 40 } 41 42 } 43 44 int main(){ 45 scanf("%d%d%d%d%d",&ja,&jb,&x,&y,&s); 46 for(int i=ja;i<=jb;i++){ 47 work(i); 48 } 49 for(int i=x;i<=y;i++){ 50 if(num[i]==s){ 51 printf("%d\n",i); 52 } 53 } 54 }
【总结】
遇见一看数据范围就很暴力的题,可以换角度下手,要么反向操作,或者预处理,或者构造满足条件的数