数位dp 等凹数字 (未完成)
2017-03-27 19:45
253 查看
广工校赛
Problem G: 等凹数字
Description
定义一种数字称为等凹数字,即从高位到地位,每一位的数字先非递增再非递减,不能全部数字一样,且该数是一个回文数,即从左读到右与从右读到左是一样的,仅形成一个等凹峰,如543212345,5544334455是合法的等凹数字,543212346,123321,111111不是等凹数字。现在问你[L,R]中有多少等凹数字呢?
Input
第一行一个整数T,表示数据的组数。
接下来T行每行俩个数字L和R,(1<=L<=R<=1e18)
Output
输出一个整数,代表[L,R]中有多少等凹数字
Sample Input
2
1 100
101 200
Sample Output
0
1
HINT
小于等于2位的数字无凹峰
//太坑了,只会套模板,这个地方不知道怎么修改成”凹峰“会错。
Problem G: 等凹数字
Description
定义一种数字称为等凹数字,即从高位到地位,每一位的数字先非递增再非递减,不能全部数字一样,且该数是一个回文数,即从左读到右与从右读到左是一样的,仅形成一个等凹峰,如543212345,5544334455是合法的等凹数字,543212346,123321,111111不是等凹数字。现在问你[L,R]中有多少等凹数字呢?
Input
第一行一个整数T,表示数据的组数。
接下来T行每行俩个数字L和R,(1<=L<=R<=1e18)
Output
输出一个整数,代表[L,R]中有多少等凹数字
Sample Input
2
1 100
101 200
Sample Output
0
1
HINT
小于等于2位的数字无凹峰
//太坑了,只会套模板,这个地方不知道怎么修改成”凹峰“会错。
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<string> #include<cstring> #include<iomanip> #include<iostream> #include<stack> #include<cmath> #include<map> #include<vector> #define ll long long #define inf 0x3f3f3f3f #define bug1 cout<<"bug1"<<endl; #define bug2 cout<<"bug2"<<endl; #define bug3 cout<<"bug3"<<endl; using namespace std; int dig[30]; int tmp[30]; int dp[30][30][2]; int dfs(int pos,int start,int flag,bool limit){ if(pos<0){ int flagsame=1; for(int i=1;i<=start;++i){ if(tmp[i]!=tmp[i-1]){ flagsame=0;break; } } if(flagsame||flagup)return 0; else return flag; } if(!limit&&dp[start][pos][flag]!=-1)return dp[start][pos][flag]; int up=limit?dig[pos]:9; int ret=0; for(int i=0;i<=up;++i){ /* if(pos>=(1+start)/2){ int flagde=0; for(int j=start;j>=pos;--j){ if(tmp[j]<i){ flagde=1;break; } } if(flagde)continue; } bug1 */ tmp[pos]=i; if(start==pos&&i==0){ ret+=dfs(pos-1,start-1,flag,limit&&dig[pos]==i); } else if(flag==1&&pos<(1+start)/2){ ret+=dfs(pos-1,start,tmp[pos]==tmp[start-pos],limit&&dig[pos]==i); } else{ ret+=dfs(pos-1,start,flag,limit&&dig[pos]==i); } } if(!limit)dp[start][pos][flag]=ret; return ret; } int solve(ll x){ memset(dig,0,sizeof(dig)); int tol=0; while(x){ dig[tol++]=x%10; x/=10; } return dfs(tol-1,tol-1,1,true); } int main(){ int t; scanf("%d",&t); int _case=0; memset(dp,-1,sizeof(dp)); solve(1e18); while(t--){ ll a,b; scanf("%lld%lld",&a,&b); if(a>b)swap(a,b); printf("Case %d: %d\n",++_case,solve(b)-solve(a-1)); } }
标程,,还没看2017年3月31日13:20:38 #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <time.h> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> using namespace std; long long dp[20][20][10][2][2][2]; int num[20]; int s[20]; long long rec(int i,int pre,int up,int down,int flag,int q,int len,int ispa) { if(i<0)return up&&down&&ispa; if(~dp[i][len][pre][up][down][ispa]&&!flag&&!q)return dp[i][len][pre][up][down][ispa]; long long res=0; int o=s[i]; for(int j=0;j<10;j++) { num[i]=j; if(j>o&&flag)break; if(q)res+=rec(i-1,j,0,0,j<o?0:flag,q&&j==0,len-(q&&j==0),ispa); else if(j==pre) { if(ispa&&i<len/2) res+=rec(i-1,j,up,down,j<o?0:flag,q&&j==0,len,j==num[len-i-1]); else res+=rec(i-1,j,up,down,j<o?0:flag,q&&j==0,len,ispa); } else if(j>pre) { if(!down)continue; if(ispa&&i<len/2) res+=rec(i-1,j,1,down,j<o?0:flag,q&&j==0,len,j==num[len-i-1]); else res+=rec(i-1,j,1,down,j<o?0:flag,q&&j==0,len,ispa); } else if(j<pre) { if(up)continue; if(ispa&&i<len/2) res+=rec(i-1,j,up,1,j<o?0:flag,q&&j==0,len,j==num[len-i-1]); else res+=rec(i-1,j,up,1,j<o?0:flag,q&&j==0,len,ispa); } } if(!flag&&!q)dp[i][len][pre][up][down][ispa]=res; return res; } long long cal(long long x) { int len=0; while(x) { s[len++]=x%10; x/=10; } return rec(len-1,0,0,0,1,1,len,1); } int main() { memset(dp,-1,sizeof(dp)); long long l,r; int t; scanf("%d",&t); while(t--){ scanf("%lld%lld",&l,&r); printf("%lld\n",cal(r)-cal(l-1)); } return 0; }
相关文章推荐
- 【BZOJ1833】【ZJOI2010】count 数字计数 (数位DP)
- 51nod 1042 数字0-9的数量(数位DP)
- [省选前题目整理][BZOJ 1833][ZJOI 2010]count 数字计数(数位DP)
- bzoj 3780: 数字统计 (数位dp)
- BZOJ 1799 self 同类分布(数位dp,区间各位数字和能整除原数的数字个数)
- 【bzoj3679】 数字之积 数位dp
- bzoj1833[ZJOI2010]count 数字计数 数位DP
- 2017广东工业大学程序设计竞赛决赛 Problem G: 等凹数字(回文+数位dp)
- POJ 3252 Round Numbers(数位dp,区间中二进制表示时0的个数大于等于1的个数的数字的个数)
- bzoj 1833: [ZJOI2010]count 数字计数(数位dp)
- BZOJ 1833: [ZJOI2010]count 数字计数 数位DP,处理前导0
- 【数位dp入门】51nod 1009 数字1的数量
- 1833: [ZJOI2010]count 数字计数——数位dp
- 【bzoj 1833】【codevs 1359】 [ZJOI2010]count 数字计数(数位dp)
- BZOJ 1833 ZJOI2010 count 数字计数 数位DP
- bzoj 1833 数字计数|数位dp
- 51nod 数字1的数量(数位DP)
- bzoj 1833 [ZJOI2010]count 数字计数(数位DP)
- [bzoj1833][ZJOI2010]count 数字计数——数位dp
- 51nod 1042 数字0-9的数量 数位DP