ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[多校联考]Contest#3-T2-琪露诺数

2019-09-24 19:53:18  阅读:210  来源: 互联网

标签:10 进制 Contest int len 露诺数 回文 联考 string


题目

【题目背景】

琪露诺是住在雾之湖的冰之妖精,在幻想乡的妖精当中算是最强的。同时她也是幻想乡首屈一指的数学家,有自己的算术教室。她喜欢用九进制来表示数字,因为这样数字中就不含$9$了。

【题目描述】

对于一个十进制数$X$,它在九进制下表示为$Y$,如果$Y$是一个回文数字,那么我们称$X$是一个琪露诺数。请你找出$[L,R]$中有多少个琪露诺数。


 

【输入格式】

第一行一个非负整数$T$,表示询问的个数。

接下来$T$行,每行两个正整数$L$和$R$,表示该组询问对应的范围$[L,R]$。


 

【输出格式】

对于每个询问,输出一个整数,表示$[L,R]$中琪露诺数的个数。


 

【样例输入】

样例输入1
1
1 10
样例输入2
4
1 100
1 1000
1 10000
18 19

【样例输出】

样例输出1
9
样例输出2
19
92
203
0

 

【数据范围】

对于样例1:[1,10]中有以下琪露诺数:1、2、3、4、5、6、7、8、10,他们在九进制下分别表示为1、2、3、4、5、6、7、8、11。

对于30%的数据,R≤10000

对于40%的数据,R≤10^12

对于50%的数据,R≤10^30

对于100%的数据,R≤10^100,T≤20,1≤L≤R

【提示】

对于任何一种进制——$X$进制,就表示每一位置上的数运算时都是逢$X$进位。十进制是逢$10$进位,十六进制是逢$16$进位,二进制就是逢$2$进位,以此类推,$X$进制就是逢$X$进位。同一个数在不同进制下可能会表示成不同的样子,比如十进制数$13$在二进制下表示为$1101$,在九进制下表示为$14$。

回文数字的定义如下:最高位的数字等于最低位的数字,次高位的数字等于次低位的数字……以此类推。比如:$22$,、$313$、$6$等都是回文数字,而$12$、$321$等不是回文数字。特别的,回文数字不考虑前导$0$,所以$20$、$110$不是回文数字,$0$是回文数字


题解

一道比较简单的高精度题(虽然我在考试的时候没做出来)

我们先把问题用差分转化成区间$[1,R]$内的数量减区间$[1,L-1]$内的数量。

注意,$L-1$可能为$0$,此时需要特判。

然后问题就转化为求区间$[1,X]$内的数量。

我们可以很快的求出九进制下小于等于某个数的最大回文数字,方法如下:

考虑这个九进制数的前半部分不变

如果构造后半部分的话,会不会比当前大,如果不会那么构造出来的就是小于等于这个数的最大回文数字

否则把前半部分看成一个数进行减$1$操作,再重新构造

注意这个过程中可能会发生位数的变化,所以我们先把$X$转化为九进制数$Y$,求出九进制下小于等于$Y$的最大回文数字$Z$,再把$Z$转化回十进制数

实现中涉及高精度的进制转换和加减法。时间复杂度$O(T*len^2)$。

注意,回文数分为长度为奇数和长度为偶数两种情况,涉及构造后半部分的不同。

CODE我知道你们只看这个

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 inline int qread(){
 4     #define cg (c=getchar())
 5     int x,f=1;char c;
 6     while(cg<'0'||'9'<c)if(c=='-')f=-1;
 7     for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
 8     return x*f;
 9     #undef cg
10 }
11 template<class T>inline T Max(const T x,const T y){return x>y?x:y;}
12 const int MAXL=200;
13 int T;
14 string l,r,c;
15 string add(const string x,const string y){
16     int a[MAXL+5]={},b[MAXL+5]={},len;
17     for(int i=0,siz=x.size();i<siz;++i)a[siz-i]=x[i]^48;
18     for(int i=0,siz=y.size();i<siz;++i)b[siz-i]=y[i]^48;
19     len=Max(x.size(),y.size());
20     for(int i=1;i<=len;++i)a[i]+=b[i],a[i+1]+=a[i]/10,a[i]%=10;
21     if(a[len+1])++len;
22     string ret;ret.clear();
23     for(int i=len;i>=1;--i)ret+=a[i]^48;
24     return ret;
25 }
26 string sub(const string x,const string y){
27     int a[MAXL+5]={},b[MAXL+5]={},len;
28     for(int i=0,siz=x.size();i<siz;++i)a[siz-i]=x[i]^48;
29     for(int i=0,siz=y.size();i<siz;++i)b[siz-i]=y[i]^48;
30     len=Max(x.size(),y.size());
31     for(int i=1;i<=len;++i){
32         a[i]-=b[i];
33         if(a[i]<0)a[i]+=10,--a[i+1];
34     }
35     while(a[len]==0&&len>1)--len;
36     string ret;ret.clear();
37     for(int i=len;i>=1;--i)ret+=a[i]^48;
38     return ret;
39 }
40 bool zero(const string x){
41     for(int i=0,siz=x.size();i<siz;++i)if(x[i]!='0')
42         return false;
43     return true;
44 }
45 string trans(string x,int n,int m){
46     if(zero(x))return "0";
47     string res,ret;res.clear(),ret.clear();
48     // cout<<"This is transform:x=="<<x<<";n=="<<n<<";m=="<<m<<endl;
49     while(!zero(x)){
50         int r=0;
51         for(int i=0,siz=x.size();i<siz;++i){
52             res+=(((r*n+x[i]-'0'))/m)+'0';
53             r=(r*n+x[i]-'0')%m;
54         }
55         x=res;
56         res.clear();
57         ret+=r+'0';
58     }
59     reverse(ret.begin(),ret.end());
60     return ret;
61 }
62 string palin(const string x){
63     if(zero(x))return "0";
64     // cout<<"come in!"<<endl;
65     bool flg=false;
66     for(int len=x.size(),i=(len-1)>>1;i>=0;--i){
67         if(x[i]==x[len-i-1])continue;
68         if(x[i]>x[len-i-1]){flg=true;break;}
69         else{flg=false;break;}
70     }
71     string a,b;a.clear(),b.clear();
72     for(int i=0,len=x.size();i<(len+1)>>1;++i)a+=x[i];
73     for(int i=0,len=x.size();i<len>>1;++i)b+='8';
74     a=trans(a,9,10);
75     if(flg)a=sub(a,"1");
76     // cout<<a<<' '<<b<<endl;
77     return add(a,trans(b,9,10));
78 }
79 signed main(){
80     T=qread();
81     while(T--){
82         cin>>l>>r;
83         l=sub(l,"1");
84         l=trans(l,10,9);
85         r=trans(r,10,9);
86         cout<<sub(palin(r),palin(l))<<endl;
87     }
88     return 0;
89 }
View Code

放心食用!

标签:10,进制,Contest,int,len,露诺数,回文,联考,string
来源: https://www.cnblogs.com/MachineryCountry/p/11580530.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有