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 }