Hdu 6156 Palindrome Function 2017 CCPC网络赛
2017-08-21 22:12
309 查看
题目链接
这是2017CCPC网络赛的题目。比赛过程中,暴力打表,二分查找过的。
由于每个进制之下的回文数大概都不会超过14万,因此,开一个二维数组储存是可以的。接下来,我们就需要找出k进制下的回文数。(这里需要提一下一个算法,第N个回文数,如果和我一样之前并不知晓请自行百度)
接下来是AC的代码
以上只是比赛时的权宜之计,比赛后,自然要用数位dp来做。
开了三维的状态 第一个代表当前位置,第二个代表进制,第三个代表开始的位置
这是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); } }
相关文章推荐
- 简单规律 HDU - 6154 CaoHaha's staff[2017 CCPC网络选拔赛]
- hdu 5838 Mountain(2016 CCPC网络赛1007) 状压
- HDU 6156 - Palindrome Function [ 数位DP ] | 2017 中国大学生程序设计竞赛 - 网络选拔赛
- hdu 5840 This world need more Zhu (2016CCPC 网络赛1009) 分块+线段树
- HDU-5832-A water problem【2016CCPC网络赛】
- HDU 6153 A Secret CCPC网络赛,KMP拓展应用
- hdu 5833 Zhu and 772002 ccpc网络赛 高斯消元法
- HDU-5835-Danganronpa【2016CCPC网络赛】
- 2017中国大学生程序设计竞赛 - 网络选拔赛 HDU 6156 数位DP
- HDU-5842-Lweb and String【2016CCPC网络赛】
- HDU 6156 2016ICPC网络赛 G: Palindrome Function(数位DP)
- HDU 5832——A water problem & 2016CCPC网络赛1001
- hdu 6152 : Friend-Graph (2017 CCPC网络赛 1003)
- A Secret 2017 CCPC 网络选拔赛 hdu 6153
- 2017中国大学生程序设计竞赛 - 网络选拔赛 && HDU 6156 Palindrome Function 【数位DP】
- HDU 5842—— Lweb and String & CCPC 网络赛 1011
- HDU-5833-Zhu and 772002【2016CCPC网络赛】【高斯消元】
- CCPC网络赛,HDU_5842 Lweb and String
- ccpc 网络赛 hdu 6155
- HDU5842——Lweb and String(CCPC网络赛第11题)