HDU 5898 odd-even number

Posted hchlqlz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 5898 odd-even number相关的知识,希望对你有一定的参考价值。

题目:odd-even number

链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5898

题意:给一个条件,问l 到r 之间有多少满足条件的数,条件是:连续的奇数长度为偶数,连续的偶数长度为奇数,比如124683,连续的奇数(1、3)长度都是1(奇数),连续的偶数(2468)长度为4(偶数),所以不满足条件。

思路:

  很明显的数位dp,可以用dfs做,传下三个参数(pre、p1、p2、ceng),pre表示前一位的数是奇数还是偶数,p1表示前面连续的奇数个数,p2表示前面连续的偶数的个数(p1、p2至少有一个为0),ceng表示还需dfs几位。如果ceng是0,那就判断,pre是偶数p2为奇数、pre是奇数p1是偶数返回1,否则返回0。如果ceng不为0,则分情况递归,比如pre为1且p1为奇数,则这一位不能选择偶数......

  然后就是根据具体的数调用dfs求数量。

  注意:区间超过longlong,要用字符串存。

AC代码:

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<stdlib.h>
  4 #include<math.h>
  5 #include<set>
  6 #include<map>
  7 #include<list>
  8 #include<stack>
  9 #include<queue>
 10 #include<vector>
 11 #include<string>
 12 #include<iostream>
 13 #include<algorithm>
 14 using namespace std;
 15 #define lson rt<<1
 16 #define rson rt<<1|1
 17 #define N 20020
 18 #define M 100010
 19 #define Mod 1000000007
 20 #define LL long long
 21 #define INF 0x7fffffff
 22 #define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;i++)
 23 #define For(i,f_start,f_end) for(int i=f_start;i<f_end;i++)
 24 #define REP(i,f_end,f_start) for(int i=f_end;i>=f_start;i--)
 25 #define Rep(i,f_end,f_start) for(int i=f_end;i>f_start;i--)
 26 #define MT(x,i) memset(x,i,sizeof(x))
 27 #define gcd(x,y) __gcd(x,y)
 28 const double PI = acos(-1);
 29 
 30 LL dfs(int pre,int p1,int p2,int ceng)
 31 {
 32   if(ceng == 0)
 33   {
 34     if(p1==0 && p2==0) return 1;
 35     else if(pre==0 && p2%2==1) return 1;
 36     else if(pre==0) return 0;
 37     else if(pre==1 && p1%2==0) return 1;
 38     else return 0;
 39   }
 40   LL ret;
 41   if(p1==0 && p2==0){
 42     ret = dfs(0,0,0,ceng-1);
 43     ret += dfs(0,0,p2+1,ceng-1)*4;
 44     ret += dfs(1,p1+1,0,ceng-1)*5;
 45 
 46   }
 47   else if(pre==0 && p2%2==0){
 48     ret=dfs(0,0,p2+1,ceng-1);
 49     ret = ret * 5;
 50   }
 51   else if(pre==0 && p2%2==1){
 52     ret=dfs(0,0,p2+1,ceng-1)*5;
 53     ret+=dfs(1,p1+1,0,ceng-1)*5;
 54   }
 55   else if(pre==1 && p1%2==1){
 56     ret=dfs(1,p1+1,0,ceng-1)*5;
 57   }
 58   else if(pre==1 && p1%2==0){
 59     ret=dfs(1,p1+1,0,ceng-1)*5;
 60     ret+=dfs(0,0,p2+1,ceng-1)*5;
 61   }
 62   return ret;
 63 }
 64 
 65 bool ok(char *x)
 66 {
 67   if(x[0]==0 && x[1]==0) return true;
 68   int pre = 0, p1 = 0, p2 = 0;
 69   int len=strlen(x)-1;
 70   while(len>=0)
 71   {
 72     int tmp = (x[len]-0)%2;
 73     if(p1==0 && p2==0);
 74     else if(tmp == 0 && pre==1 && p1%2==1) return false;
 75     else if(tmp == 1 && pre==0 && p2%2==0) return false;
 76     if(tmp == 0 ) p2++,p1=0;
 77     else p1++,p2=0;
 78     pre=tmp;
 79     len--;
 80   }
 81   if(pre==0 && p2%2==0) return false;
 82   if(pre==1 && p1%2==1) return false;
 83   return true;
 84 }
 85 
 86 bool ok(int x)
 87 {
 88   if(x==0) return true;
 89   int pre = 0, p1 = 0, p2 = 0;
 90   while(x)
 91   {
 92     int tmp = x%10%2;
 93     if(p1==0 && p2==0);
 94     else if(tmp == 0 && pre==1 && p1%2==1) return false;
 95     else if(tmp == 1 && pre==0 && p2%2==0) return false;
 96     if(tmp == 0 ) p2++,p1=0;
 97     else p1++,p2=0;
 98     pre=tmp;
 99     x/=10;
100   }
101   if(pre==0 && p2%2==0) return false;
102   if(pre==1 && p1%2==1) return false;
103   return true;
104 }
105 
106 LL solve(char *x)
107 {
108   LL ret = 0;
109   if(ok(x)){
110     ret++;
111   }
112   int bt[100],bo=0;
113   while(x[bo])
114   {
115     bt[bo]=x[bo]-0;
116     bo++;
117   }
118   int tmp = 0;
119   while(tmp<=(bo-1)/2){
120     int tt = bt[tmp];
121     bt[tmp]=bt[bo-tmp-1];
122     bt[bo-tmp-1]=tt;
123     tmp++;
124   }
125   int pre = 0, p1 = 0, p2 = 0;
126   for(int i=bo-1;i>=0;i--)
127   {
128     if(bt[i]>0)
129     {
130       if(p1 == 0 && p2==0)
131         ret += dfs(pre,0,0,i);
132       else
133       {
134         if(pre == 1 && p1 % 2 == 1 );
135         else ret += dfs(0,0,p2+1,i);
136       }
137     }
138     for(int j=1;j<bt[i];j++)
139     {
140       if(j%2==1){
141         if((p1!=0 || p2!=0) && pre == 0 && p2 % 2 == 0) continue;
142         else ret += dfs(1,p1+1,0,i);
143       }
144       else
145       {
146         if(pre == 1 && p1 % 2 == 1) continue;
147         ret += dfs(0,0,p2+1,i);
148       }
149     }
150     if(p1==0 && p2==0);
151     else if(bt[i]%2==0 && pre==1 && p1%2==1) break;
152     else if(bt[i]%2==1 && pre==0 && p2%2==0) break;
153     pre = bt[i]%2;
154     if(pre==0) p2++,p1=0;
155     else p1++,p2=0;
156   }
157   return ret;
158 }
159 
160 int main()
161 {
162   int t;
163   char l[100],r[100];
164   int cas=1;
165   scanf("%d",&t);
166   while(t--){
167     scanf("%s%s",l,r);
168     printf("Case #%d: ",cas++);
169     printf("%I64d\n",solve(r)-solve(l)+(ok(l)?1:0));
170   }
171   return 0;
172 }

以上是关于HDU 5898 odd-even number的主要内容,如果未能解决你的问题,请参考以下文章

HDU 5898 odd-even number 数位DP

hdu 5898 odd-even number(数位dp)

hdu 5898 odd-even number 数位dp

hdu 5898 odd-even number 数位DP

[暑假集训--数位dp]hdu5898 odd-even number

hdu5898 odd-even number(数位dp)