[vijos1162]波浪数

题目链接: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 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 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<p;i++){//首位不为0 
31         for(int j=0;j<p;j++){
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 }    
View Code

【总结】

遇见一看数据范围就很暴力的题,可以换角度下手,要么反向操作,或者预处理,或者构造满足条件的数

 

posted @ 2017-10-25 15:16  Danzel♂  阅读(334)  评论(0编辑  收藏  举报