UESTC 1137 邱老师选妹子

来源:互联网 发布:水利造价软件 天宇 编辑:程序博客网 时间:2024/04/28 09:28

邱老师选妹子

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
 

邱老师长得帅这是人尽皆知,于是追他的妹子就会很多。

但是你知道,邱老师是一个很专一的人,所以他心里面只能有一个人。

于是他决定从追他的众多妹子里挑选一个出来。于是酱神给邱老师出来一个主意,已知有一些妹子,恰好可以给她们从l到r排号,使得每一个妹子有单独

的数字,而正好有r-l+1个妹子。酱神说,我们不能要运气不好的女孩,而酱神又给了两个数字62和4,如果妹子的排号里面有62(必须是连续的)或4,那么

就排除他现在给你l和r,问有多少妹子可以有幸在第一轮留下。

Input

输入的都是整数对l、r(0<l≤r<1000000),如果遇到都是0的整数对,则输入结束。

Output

每组数据输出占一行,对于每个l和r 输出有多少个妹子可以在第一轮不被排除


杭电原题,不要62。

数据量比较小,可以直接暴力,这里就不贴暴力了,用数位DP做一下.

dp[i][0]表示长度小于等于i,符合题意的数的个数。

dp[i][1]表示长度为i,首位为2的个数。

那么就有转移方程:

dp[i][0]=(dp[i-1][0]-dp[i-1][1])*9+8*dp[i-1][1]=dp[i-1][0]*9-dp[i-1][1]

然后给定了一个abcd 

计算1-abcd有多少个的时候,a*dp[3][0]+b*dp[2][0]+c*dp[1][0]+d*dp[0][0]

但是如果某一位是4 或者超过4 或者出现了62那么就要处理一下。

因为处理的时候对于一个n没有把自己合不合法考虑进去,所以输入left和right的时候计算cal(right+1)-cal(left)

代码:

//************************************************************************////*Author : Handsome How                                                 *////************************************************************************////#pragma comment(linker, "/STA    CK:1024000000,1024000000")#pragma warning(disable:4996)#include <vector>#include <map>#include <set>#include <deque>#include <queue>#include <stack>#include <algorithm>#include <sstream>#include <iostream>#include <cstdio>#include <cmath>#include <cstdlib>#include <cstring>#include <ctime>#include <cassert>#if defined(_MSC_VER) || __cplusplus > 199711L#define aut(r,v) auto r = (v)#else#define aut(r,v) __typeof(v) r = (v)#endif#define each(it,o) for(aut(it, (o).begin()); it != (o).end(); ++ it)#define fur(i,a,b) for(int i=(a);i<=(b);i++)#define furr(i,a,b) for(int i=(a);i>=(b);i--)#define cl(a) memset((a),0,sizeof(a))#define mp make_pair#define pb push_back#define fi first#define se second#define sc(x) scanf("%d",&x)using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair <int, int> pii;const int inf=0x3f3f3f3f;const double eps=1e-8;const int mod=1000000007;const double pi=acos(-1);inline void gn(long long&x){    int sg=1;char c;while(((c=getchar())<'0'||c>'9')&&c!='-');c=='-'?(sg=-1,x=0):(x=c-'0');    while((c=getchar())>='0'&&c<='9')x=x*10+c-'0';x*=sg;}inline void gn(int&x){long long t;gn(t);x=t;}inline void gn(unsigned long long&x){long long t;gn(t);x=t;}inline void gn(double&x){double t;scanf("%lf",&t);x=t;}inline void gn(long double&x){double t;scanf("%lf",&t);x=t;}//----------------------------------------------------------int dp[10][2];        //dp[i][0]  满足条件的长度小于=i的数                    //dp[i][1]  满足条件的2开头的长度小于=i的数                 void init(){    cl(dp);    dp[0][0]=1;    fur(i,1,9){        dp[i][0]=dp[i-1][0]*9-dp[i-1][1];        dp[i][1]=dp[i-1][0];    }}int calc(int n){    if(n==1)return 1;    int k = n;    int numb[10];    int t = 0;    bool okn = false;    while(n){        numb[++t] = n%10;        n/=10;    }    int ans = 0;    furr(i,t,1){        if(numb[i+1]==4||(numb[i+1]==2)&&numb[i+2]==6)break;        if(numb[i]==0)continue;        if(numb[i]>=7)ans=ans+(numb[i]-1)*dp[i-1][0]-dp[i-1][1];        if(numb[i]<=4)ans=ans+numb[i]*dp[i-1][0];        if(numb[i]==5||numb[i]==6)ans=ans+(numb[i]-1)*dp[i-1][0];        if(numb[i+1]==6&&numb[i]>=3)ans=ans-dp[i][1];    }        return ans;}int main(){    //freopen("E:\\data.in", "r", stdin);    ios :: sync_with_stdio(false);    init();    int l,r;    while(scanf("%d %d",&l,&r)){        if(l>r){        printf("0\n");        continue;            }        if(!l&&!r)return 0;        int ll=calc(l);        int rr=calc(r+1);        int ans=rr-ll;        printf("%d\n",ans);    }    return 0;}









0 0
原创粉丝点击