题目: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代码:

 #include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<set>
#include<map>
#include<list>
#include<stack>
#include<queue>
#include<vector>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
#define lson rt<<1
#define rson rt<<1|1
#define N 20020
#define M 100010
#define Mod 1000000007
#define LL long long
#define INF 0x7fffffff
#define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;i++)
#define For(i,f_start,f_end) for(int i=f_start;i<f_end;i++)
#define REP(i,f_end,f_start) for(int i=f_end;i>=f_start;i--)
#define Rep(i,f_end,f_start) for(int i=f_end;i>f_start;i--)
#define MT(x,i) memset(x,i,sizeof(x))
#define gcd(x,y) __gcd(x,y)
const double PI = acos(-); LL dfs(int pre,int p1,int p2,int ceng)
{
if(ceng == )
{
if(p1== && p2==) return ;
else if(pre== && p2%==) return ;
else if(pre==) return ;
else if(pre== && p1%==) return ;
else return ;
}
LL ret;
if(p1== && p2==){
ret = dfs(,,,ceng-);
ret += dfs(,,p2+,ceng-)*;
ret += dfs(,p1+,,ceng-)*; }
else if(pre== && p2%==){
ret=dfs(,,p2+,ceng-);
ret = ret * ;
}
else if(pre== && p2%==){
ret=dfs(,,p2+,ceng-)*;
ret+=dfs(,p1+,,ceng-)*;
}
else if(pre== && p1%==){
ret=dfs(,p1+,,ceng-)*;
}
else if(pre== && p1%==){
ret=dfs(,p1+,,ceng-)*;
ret+=dfs(,,p2+,ceng-)*;
}
return ret;
} bool ok(char *x)
{
if(x[]=='' && x[]==) return true;
int pre = , p1 = , p2 = ;
int len=strlen(x)-;
while(len>=)
{
int tmp = (x[len]-'')%;
if(p1== && p2==);
else if(tmp == && pre== && p1%==) return false;
else if(tmp == && pre== && p2%==) return false;
if(tmp == ) p2++,p1=;
else p1++,p2=;
pre=tmp;
len--;
}
if(pre== && p2%==) return false;
if(pre== && p1%==) return false;
return true;
} bool ok(int x)
{
if(x==) return true;
int pre = , p1 = , p2 = ;
while(x)
{
int tmp = x%%;
if(p1== && p2==);
else if(tmp == && pre== && p1%==) return false;
else if(tmp == && pre== && p2%==) return false;
if(tmp == ) p2++,p1=;
else p1++,p2=;
pre=tmp;
x/=;
}
if(pre== && p2%==) return false;
if(pre== && p1%==) return false;
return true;
} LL solve(char *x)
{
LL ret = ;
if(ok(x)){
ret++;
}
int bt[],bo=;
while(x[bo])
{
bt[bo]=x[bo]-'';
bo++;
}
int tmp = ;
while(tmp<=(bo-)/){
int tt = bt[tmp];
bt[tmp]=bt[bo-tmp-];
bt[bo-tmp-]=tt;
tmp++;
}
int pre = , p1 = , p2 = ;
for(int i=bo-;i>=;i--)
{
if(bt[i]>)
{
if(p1 == && p2==)
ret += dfs(pre,,,i);
else
{
if(pre == && p1 % == );
else ret += dfs(,,p2+,i);
}
}
for(int j=;j<bt[i];j++)
{
if(j%==){
if((p1!= || p2!=) && pre == && p2 % == ) continue;
else ret += dfs(,p1+,,i);
}
else
{
if(pre == && p1 % == ) continue;
ret += dfs(,,p2+,i);
}
}
if(p1== && p2==);
else if(bt[i]%== && pre== && p1%==) break;
else if(bt[i]%== && pre== && p2%==) break;
pre = bt[i]%;
if(pre==) p2++,p1=;
else p1++,p2=;
}
return ret;
} int main()
{
int t;
char l[],r[];
int cas=;
scanf("%d",&t);
while(t--){
scanf("%s%s",l,r);
printf("Case #%d: ",cas++);
printf("%I64d\n",solve(r)-solve(l)+(ok(l)?:));
}
return ;
}

HDU 5898 odd-even number的更多相关文章

  1. HDU 5898:odd-even number(数位DP)

    http://acm.hdu.edu.cn/showproblem.php?pid=5898 题意:给出一个区间[l, r],问其中数位中连续的奇数长度为偶数并且连续的偶数长度为奇数的个数.(1< ...

  2. hdu 5898 odd-even number 数位DP

    传送门:hdu 5898 odd-even number 思路:数位DP,套着数位DP的模板搞一发就可以了不过要注意前导0的处理,dp[pos][pre][status][ze] pos:当前处理的位 ...

  3. HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

  4. hdu 6216 A Cubic number and A Cubic Number【数学题】

    hdu 6216 A Cubic number and A Cubic Number[数学] 题意:判断一个素数是否是两个立方数之差,就是验差分.. 题解:只有相邻两立方数之差才可能,,因为x^3-y ...

  5. HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)

    HDU 1394 Minimum Inversion Number(线段树求最小逆序数对) ACM 题目地址:HDU 1394 Minimum Inversion Number 题意:  给一个序列由 ...

  6. HDU 6093 - Rikka with Number | 2017 Multi-University Training Contest 5

    JAVA+大数搞了一遍- - 不是很麻烦- - /* HDU 6093 - Rikka with Number [ 进制转换,康托展开,大数 ] | 2017 Multi-University Tra ...

  7. hdu 5898 odd-even number(数位dp)

    Problem Description For a number,if the length of continuous odd digits is even and the length of co ...

  8. HDU 5898 odd-even number(2016沈阳网络选拔赛 数位DP)

    定义DP[pos][pre][odd][even],pos代表当前数位,pre代表前一位的数值,odd代表到前一位连续的奇数个数,even代表到前一位连续偶数个数. odd和even肯定至少有一个为0 ...

  9. HDU 5898 odd-even number (数位DP) -2016 ICPC沈阳赛区网络赛

    题目链接 题意:一个数字,它每个数位上的奇数都形成偶数长度的段,偶数位都形成奇数长度的段他就是好的.问[L , R]的好数个数. 题解:裸的数位dp, 从高到低考虑每个数位, 状态里存下到当前位为止的 ...

随机推荐

  1. 2018年6月,最新php工程师面试总结

    面试经常被问到的问题总结 1.字符串函数 2.数组函数 3.cookie和session的区别 4.状态码以及其功能

  2. java8中的接口与时间操作

    java8中接口可以有默认方法(用default修饰,可以有多个)和静态方法了. public interface Tran { default public String getName() { r ...

  3. YOLO 从数据集制作到训练

    1.图片数据集收集 共 16种 集装箱船 container ship 散货船 bulker 油船 tanker 游轮 / 客轮 / 邮轮 passenger liner 渔船 fishing boa ...

  4. [matlab] 10.最小覆盖

    clear all; close all; clc; n=100; p=rand(n,2); p1=p(1,:); %取第一行的值 P1点 p2=p(2,:); %取第二行的值 P2点 r=sqrt( ...

  5. 小a的排列

    链接:https://ac.nowcoder.com/acm/contest/317/G来源:牛客网 小a有一个长度为nn的排列.定义一段区间是"萌"的,当且仅当把区间中各个数排序 ...

  6. PAT A1052 Linked List Sorting (25 分)——链表,排序

    A linked list consists of a series of structures, which are not necessarily adjacent in memory. We a ...

  7. 浅谈文件断点续传和WebUploader的基本结合

    0.写在前面的话 上篇博客已经是在8月了,期间到底发生了什么,只有我自己知道,反正就是心情特别糟糕,生活状态工作状态学习状态都十分不好,还有心思进取吗,No!现在状态好起来了,生活又充满了希望 :D  ...

  8. Tencent Cloud Developers Conference(2018.12.15)

    时间:2018.12.15地点:北京朝阳悠唐皇冠假日酒店

  9. [HNOI2019]多边形[二叉树建模、组合计数]

    题意 题目链接 分析 不难发现终态一定是 \([2,n-2]\) 中的每个点都与 \(n\) 连边. 关于凸多边形的划分问题,可以将它看作一棵二叉树:每个树点可以看做点可以看做边. 本题中看做点来处理 ...

  10. 使用Filter过滤器+重写Request完美解决乱码问题

    一:原理 1.对于Post方式提交的数据,我们可以通过直接设置request和response的编码方式来解决乱码问题:但是Get方式提交的数据,那么就需要编码再解码的方式解决乱码问题. 2.我们一般 ...