H - 邱老师选妹子
Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
Submit Status
邱老师长得帅这是人尽皆知,于是追他的妹子就会很多。
但是你知道,邱老师是一个很专一的人,所以他心里面只能有一个人。
于是他决定从追他的众多妹子里挑选一个出来。于是酱神给邱老师出来一个主意,已知有一些妹子,恰好可以给她们从l到r排号,使得每一个妹子有单独的数字,而正好有r-l+1个妹子。
酱神说,我们不能要运气不好的女孩,而酱神又给了两个数字62和4,如果妹子的排号里面有62(必须是连续的)或4,那么就排除他现在给你l和r,问有多少妹子可以有幸在第一轮留下。
Input
输入的都是整数对l、r(0<l≤r<1000000),如果遇到都是0的整数对,则输入结束。
Output
每组数据输出占一行,对于每个l和r 输出有多少个妹子可以在第一轮不被排除
Sample input and output
Sample Input | Sample Output |
---|---|
1 100 0 0 | 80 |
Hint
不好的数字为所有含有4或62的号码。例如:
62315 73418 88914
都属于不好的。但是,61152虽然含有6和2,但不是62连号
解题报告:
我们考虑f( a , b , c , d , e) -> 正在转移第 a 位,且前一位是 b ,c 表示是否小于过上界, d 表示是否大于过下界 , e 表示目前的状态 的合法方案数.
转移时通过 c 和 d来确定枚举的上下界,同时注意上一位数和status进行枚举和转移.
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> typedef long long ll; using namespace std; ll f[22][22][2][2][2]; string A,B; int len; ll dfs(int cur,int front,int f1,int f2,int status) { if (f[cur][front][f1][f2][status] != -1) return f[cur][front][f1][f2][status]; ll & ans = f[cur][front][f1][f2][status] = 0; if (cur == len) return ans = status; int st = f1 ? 0 : A[cur]-'0'; int ed = f2 ? 9 : B[cur]-'0'; for(int i = st ; i <= ed ; ++ i) { if (i == 4) ans += dfs(cur+1,i,f1 | i > A[cur]-'0' , f2 | i < B[cur] - '0',0); else if (i == 2) { if (front == 6) ans += dfs(cur+1,i,f1 | i > A[cur]-'0' , f2 | i < B[cur] - '0',0); else ans += dfs(cur+1,i,f1 | i > A[cur]-'0' , f2 | i < B[cur] - '0',status); } else ans += dfs(cur+1,i,f1 | i > A[cur]-'0' , f2 | i < B[cur] - '0',status); } return ans; } int main(int argc,char *argv[]) { ios::sync_with_stdio(false); while(cin >> A >> B) { if (A[0] == '0' && B[0] == '0') break; memset(f,-1,sizeof(f)); len = B.size(); while(A.size() != B.size()) // Init; A = '0' + A; cout << dfs(0,0,0,0,1) << endl; } return 0; }