Hdu 6156 Palindrome Function 2017 CCPC网络赛
来源:互联网 发布:网络大v颠倒是非 编辑:程序博客网 时间:2024/06/07 14:52
题目链接
这是2017CCPC网络赛的题目。比赛过程中,暴力打表,二分查找过的。
由于每个进制之下的回文数大概都不会超过14万,因此,开一个二维数组储存是可以的。接下来,我们就需要找出k进制下的回文数。(这里需要提一下一个算法,第N个回文数,如果和我一样之前并不知晓请自行百度)
//贴一下自己修改了的求k进制下第n个回文数的代码long long Find(int n,int k) { long long Count = 0,num = k-1,w = 0,h = 1; long long half,res; while(true) { if(w > 0 && w%2 == 0) { num *= k; } w++; if(Count + num > n) break; Count += num; } n -= Count; for(int i = 0; i < (w-1) / 2; i++) { h *= k; } half = h + n; res = half; if(w%2 != 0) half /=k; while(half != 0) { res = res *k + half % k; half /= k; } return res;}
接下来是AC的代码
#include<bits/stdc++.h>using namespace std;typedef long long ll;const ll maxn = 1e9;ll a[37][150040];int Cnt[36];long long Find(int n,int k) { long long Count = 0,num = k-1,w = 0,h = 1; long long half,res; while(true) { if(w > 0 && w%2 == 0) { num *= k; } w++; if(Count + num > n) break; Count += num; } n -= Count; for(int i = 0; i < (w-1) / 2; i++) { h *= k; } half = h + n; res = half; if(w%2 != 0) half /=k; while(half != 0) { res = res *k + half % k; half /= k; } return res;}void init(){ for(int i=2;i<=36;i++) { int cnt = 0; for(int j=0;;j++) { ll temp = Find(j,i); if(temp>maxn) break; a[i][cnt++] = temp; } Cnt[i] = cnt; }}int main(){ init(); int T; scanf("%d",&T); for(int tt=1;tt<=T;tt++) { ll L,R,l,r; scanf("%lld %lld %lld %lld",&L,&R,&l,&r); int temp; ll ans =0; for(ll i=l;i<=r;i++) { temp = upper_bound(a[i],a[i]+Cnt[i],R)-lower_bound(a[i],a[i]+Cnt[i],L); ans += temp*i+(R-L+1-temp); } printf("Case #%d: %lld\n",tt,ans); }}
以上只是比赛时的权宜之计,比赛后,自然要用数位dp来做。
开了三维的状态 第一个代表当前位置,第二个代表进制,第三个代表开始的位置
#include <bits/stdc++.h>using namespace std;typedef long long ll;ll dp[40][40][40];int an[40],Num[40];ll dfs(int pos,int flag,int base,bool limit,int be){ if(pos<0) return flag==0; if(dp[pos][base][be]!=-1&&!limit&&!flag) return dp[pos][base][be]; ll res=0; int maxn=limit?Num[pos]:(base-1); for(int i=0;i<=maxn;i++) { if(flag&&i==0) res+=dfs(pos-1,flag,base,limit&&i==maxn,be); else{ if(flag){ an[pos]=i; res+=dfs(pos-1,0,base,limit&&i==maxn,pos); } else if(pos<(be+1)/2){ if(i==an[be-pos]) res+=dfs(pos-1,0,base,limit&&i==maxn,be); } else{ an[pos]=i; res+=dfs(pos-1,0,base,limit&&i==maxn,be); } } } an[pos]=-1; if(!limit&&!flag) dp[pos][base][be]=res; return res;}ll solve(int x,int base){ int len=0; while(x) { Num[len++]=x%base; x/=base; } return dfs(len-1,1,base,1,39);}int main(){ int T; scanf("%d",&T); memset(dp,-1,sizeof(dp)); for(int tt=1;tt<=T;tt++) { int l,r,L,R; scanf("%d%d%d%d",&l,&r,&L,&R); ll ans=0; for(int i=L;i<=R;i++) { ll ret=solve(r,i)-solve(l-1,i); ans+=ret*i+(r-l+1-ret); } printf("Case #%d: %lld\n",tt,ans); }}
阅读全文
0 0
- Hdu 6156 Palindrome Function 2017 CCPC网络赛
- HDU 6156 Palindrome Function(数位 回文串 17CCPC网络赛)
- Hdu 6156 Palindrome Function
- HDU 6156 Palindrome Function
- hdu 6156 Palindrome Function
- hdu 6156 Palindrome Function
- HDU-6156 Palindrome Function
- HDU-2017中国大学生程序设计竞赛-网络选拔赛-1007-Palindrome Function
- HDU 6156 2016ICPC网络赛 G: Palindrome Function(数位DP)
- 2017ccpc网络赛
- HDU-5835-Danganronpa【2016CCPC网络赛】
- CCPC 网络赛 2017 经验总结
- 2017 CCPC 网络赛 1007
- hdu 6156 Palindrome Function 数位DP
- HDU 6156 Palindrome Function 经典数位DP
- HDU-6156 Palindrome Function(找规律)
- HDU 6156 Palindrome Function 数位DP
- Hdu 6156 Palindrome Function【数位Dp】
- mysql中模糊查询的用法介绍
- RESTful的原则
- android局部更新(RecyclerView+ DiffUtil)
- 第六章 Realm及相关对象(一) Realm
- VS2015+opencv3.1.0环境搭建
- Hdu 6156 Palindrome Function 2017 CCPC网络赛
- 说说 JAVA 代理模式
- 读书笔记【2017/8/21-list接口总结】
- Spark2.2.0 + Scala2.13.0集群搭建
- 【面经笔记】好未来
- left join,right join,inner join 的区别
- 负载均衡
- Ubuntu14.04下载Lineage OS 14.1源码
- HDU-6152 Friend-Graph (思维+暴力)