HDU 6156 Palindrome Function(数位 回文串 17CCPC网络赛)
来源:互联网 发布:淘宝发货后立即回款 编辑:程序博客网 时间:2024/06/05 16:02
题目大意
定义:f(n,k)={k1如果n在k进制下是一个回文数否则
让你求∑i=LR∑j=lrf(i,j)
分析
这道题可以将问题简化成求:
给你一个数n(十进制),问你在k进制下不超过n的回文数有多少个
这道题我的做法有点冗余了,改了好久找了一份AC代码对拍才改过的。
设n在k进制下长度为m,用数组表示为
a[1...len] 先分类:- 长度小于m的回文数的个数,这个比较好求,初始化以下就行
- 长度等于m的回文数的个数,又分为两类
1.首位元素小于a[1]
2.首位元素为a[1]
定义了一个函数Less(int ch[],int len,int k),ch[]用来保存k进制下的数
定义num1[m][k] 表示长为m在k进制下的回文数的个数,开头可以是0
定义num1[m][k] 表示长为m在k进制下的回文数的个数,开头不能是0
这个函数表示小于长为len小于等于ch的数的个数(需要注意的是这里的数可以是以0开头的)由于Less找的是可以以0开头的数,所以在最外层中还要减去开头是0的情况数也就是
num[len−2][k] 需要处理边界条件是len为0 1 2 的情况
总结
像这样的题,以后一定要多想想有没有简单一点的实现方式代码
#include <iostream>#include <cstdio>#include <cstring>#include <math.h>#include <algorithm>#include <queue>using namespace std;#define LL long long intconst int MAXL=110;int num1[MAXL][40];//开头可以为0int num2[MAXL][40];//开头不能为0int Pow(int n,int k){ int ans=1; for(int i=1;i<=k;i++)ans*=n; return ans;}void Make_num1(){ for (int i=1;i<=100;i++) for (int j=2;j<=36;j++) { if (i==1) num1[i][j]=j; else num1[i][j]=Pow(j,(i+1)/2); }}void Make_num2(){ for (int i=1;i<=100;i++) for (int j=2;j<=36;j++) { if (i==1) num2[i][j]=j; else num2[i][j]=(j-1)*Pow(j,(i-1)/2); }}int Make_ch(int ch[],int n,int k)///把1个十进制的数转换成k进制{ int len=0; while (n) { ch[++len]=n%k; n/=k; } return len;}bool is_Palindrome(int ch[],int len){ bool flag=true; for (int i=1;i<=len/2;i++) if (ch[i]!=ch[len-i+1]) { flag=false; break; } return flag;}int Less(int ch[],int len,int k)//k进制下不超过n首可以为0的个数{ int res=0; if (len==0) return 1; if (len==1) return (ch[len]+1); if (len==2) { if(ch[len]<=ch[1])return ch[len]+1; else return ch[len]; } ///长度等于len且第一位比当前小的回文数 边界 res+=(ch[len]*num1[len-2][k]); ///长度等于len且第一位等于当前第一位的回文数 int p=0; int temp[MAXL];int len2=0; for (int i=2;i<=len-1;i++) { temp[++len2]=ch[i]; p+=ch[i]*Pow(k,len2-1); } res+=Less(temp,len2,k); if (ch[1]<ch[len]&&is_Palindrome(temp,len2)) res--; return res;}int Work(int n,int k){ int ans=0; int ch[MAXL]; int len=Make_ch(ch,n,k); if (len==0) return 1; if (len==1) return (ch[1]+1); if (len==2) { if(ch[len]<=ch[1])return ch[len]+k; else return ch[len]-1+k; } ans=Less(ch,len,k); for (int i=0;i<len;i++) ans+=num2[i][k];///长度小于len的回文数 ans-=num1[len-2][k];//Less(p,k); return ans;}int main(){ //freopen("data.txt","r",stdin); //freopen("out1.txt","w",stdout); Make_num1(); Make_num2(); int T,L,R,l,r,j,cnt=0; LL ans=0; scanf("%d",&T); while (T--) { scanf("%d%d%d%d",&L,&R,&l,&r); ans=0; for (j=l;j<=r;j++) { int x=Work(R,j)-Work(L-1,j); int sum=R-L+1; ans+=(x*j+sum-x); } printf("Case #%d: %lld\n",++cnt,ans); } return 0;}/*31 1 2 361 982180 10 10496690841 524639270 5 20*/
阅读全文
0 0
- HDU 6156 Palindrome Function(数位 回文串 17CCPC网络赛)
- Hdu 6156 Palindrome Function 2017 CCPC网络赛
- hdu 6156 Palindrome Function【数位dp求回文数】
- 【HDU6156】Palindrome Function(数位DP+回文串)
- HDU 6156 2016ICPC网络赛 G: Palindrome Function(数位DP)
- hdu 6156 Palindrome Function 数位DP
- HDU 6156 Palindrome Function 经典数位DP
- HDU 6156 Palindrome Function 数位DP
- Hdu 6156 Palindrome Function【数位Dp】
- HDU 6156 Palindrome Function(数位DP)
- HDU-6156 Palindrome Function(数位DP)
- HDU 6156(Palindrome Function-数位dp)
- HDU 6156 Palindrome Function (数位dp)
- HDU 6156 Palindrome Function【数位dp】
- hdu 6156 Palindrome Function(数位dp&&其他)
- hdu 6156 Palindrome Function(数位dp)
- hdu 6156 palindrome function #数位dp 3
- HDU 6156 回文 数位DP(2017CCPC)
- Firefox浏览器设置字符编码格式
- Oracle数据库基础二:DQL
- super关键字,this关键字,及其两者区别.final关键字
- 学习笔记TF042:TF.Learn、分布式Estimator、深度学习Estimator
- nyoj 27水池数目
- HDU 6156 Palindrome Function(数位 回文串 17CCPC网络赛)
- 62.寻找路径
- Girls and Boys||HDU1068
- NSThread
- A. Generous Kefa(Round #429 (Div. 2))
- 自定义分页类
- 使用Enounce MySpeed对flv加速播放
- ORACLE闪回技术
- Python3之读写Excel操作