dp-史上最戳最长最臭代码-hdu-4733-G(x)
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4733
题目大意:
定义G(x)=x⊕(x>>1).给两个由0、1、?组成的长度相同的字符串S1,S2.其中?表示0、1状态不确定,求有多少种p,使得G(p)=S1,G(p+1)=S2
如果p唯一,则输出G(p)和G(p+1)(注意这中间不能有问号)。
解题思路:
这是我写的史上最臭最长最戳的代码,大神请跳过。
分析函数G(x)=x⊕(x>>1) 也就是右移一位再抑或,从高位出发,构造p和p+1串,先分别放一个0到p和p+1(右移高位时补零的),然后根据S1和S2的状态以及p和p+1的前一状态构造出当前的p和p+1状态,
构造方法:
若S='0'则当前的p和前一位p相同,否则相反(0《-》1)
如果S='?',则可以尝试00 01 10 11四种状态。
再来分析p和p+1的特点。
1、最低位肯定不一样。
2、除最后一位外,前面每一位要么相同,要么p<p+1,如果前面某一位p<p+1(也就是01),后面的p一定全部为1,后面p+1一定全部为0.
综合G(x)和p与p+1的特点,可以构造dp状态,
dp[i][j][0][len]:表示当p的第len位为i,p+1的第len位为j,且p<q时的总数。
dp[i][j][1][len]:表示当p的第len位为i,p+1的第len位为j,且p=q时的总数。
根据当前的S和前面一位的状态可以递推出当前的位的P和p+1。
注意:
1、最后一位要单独处理。(01或10)
2、只有一种的情况时要记录路径 ,把S中的?确定下来。
比如? ? 答案为0,1而不是?,?
代码:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#define eps 1e-6
#define INF 0x3fffffff
#define PI acos(-1.0)
#define ll __int64
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std; #define Maxn 110000
#define M 1000000007 //分别记录达到该状态时的上一状态的第一串和第二串的值,以及是否相等的状态
int path1[2][2][2][Maxn],path2[2][2][2][Maxn],path3[2][2][2][Maxn];
int dp[2][2][2][Maxn];
char sa1[Maxn],sa2[Maxn];
char ans1[Maxn],ans2[Maxn]; int main()
{
int tt; scanf("%d",&tt);
for(int ca=1;ca<=tt;ca++)
{
scanf("%s%s",sa1+1,sa2+1);
int len=strlen(sa1+1);
memset(dp,-1,sizeof(dp));
path2[0][0][1][0]=path1[0][0][1][0]=-1;
path3[0][0][1][0]=-1; int la1=0,la2=0;
dp[0][0][1][0]=1; //第三维1表示相等 0表示小于
for(int i=1;i<=len;i++)
{
if(sa1[i]!='?'&&sa2[i]!='?')
{
for(int la1=0;la1<=1;la1++)
for(int la2=0;la2<=1;la2++)
{
int p,q;
p=(sa1[i]=='0')?(la1):(la1^1); //构造出当前状态
q=(sa2[i]=='0')?(la2):(la2^1); for(int t=0;t<=1;t++)
{
if(dp[la1][la2][t][i-1]==-1)//前面状态无效
continue;
if(i==len) //最后一位单独处理
{
if(p==q) //最后一位只能是0、1或者1,0
continue;
if(p) //P串中为1时,P+1串肯定为0
{
if(!t) //并且前面P<P+1
{
if(dp[p][q][1][len]==-1)
dp[p][q][1][len]=dp[la1][la2][0][len-1];
else
dp[p][q][1][len]+=dp[la1][la2][0][len-1];
dp[p][q][1][len]%=M;
path1[p][q][1][len]=la1;
path2[p][q][1][len]=la2;
path3[p][q][1][len]=t;
}
}
else //为0 1
{
if(t) //前面必须相等
{
if(dp[p][q][1][len]==-1)
dp[p][q][1][len]=dp[la1][la2][0][len-1];
else
dp[p][q][1][len]+=dp[la1][la2][0][len-1];
dp[p][q][1][len]%=M;
path1[p][q][1][len]=la1;
path2[p][q][1][len]=la2;
path3[p][q][1][len]=t;
}
}
continue;
}
if(!t) //小于的情况
{
if(p!=1||q!=0) //P 必须为1 P+1必须为0
continue;
if(dp[p][q][t][i]==-1)
dp[p][q][t][i]=dp[la1][la2][t][i-1];
else
dp[p][q][t][i]+=dp[la1][la2][t][i-1];
dp[p][q][t][i]%=M;
path1[p][q][t][i]=la1;
path2[p][q][t][i]=la2;
path3[p][q][t][i]=t;
}
else //等于的情况
{
if(p>q) //这种情况不存在
continue;
if(dp[la1][la2][t][i-1]==-1)
continue;
if(p<q) //0,1 当前小于
{
if(dp[p][q][0][i]==-1)
dp[p][q][0][i]=dp[la1][la2][t][i-1];
else
dp[p][q][0][i]+=dp[la1][la2][t][i-1];
dp[p][q][0][i]%=M;
path1[p][q][0][i]=la1;
path2[p][q][0][i]=la2;
path3[p][q][0][i]=t;
}
else //等于
{
if(dp[p][q][1][i]==-1)
dp[p][q][1][i]=dp[la1][la2][t][i-1];
else
dp[p][q][1][i]+=dp[la1][la2][t][i-1];
dp[p][q][1][i]%=M;
path1[p][q][1][i]=la1;
path2[p][q][1][i]=la2;
path3[p][q][1][i]=t;
}
}
}
}
}
else if(sa1[i]=='?'&&sa2[i]=='?')
{
for(int la1=0;la1<=1;la1++)
for(int la2=0;la2<=1;la2++)
{
for(int t=0;t<=1;t++)
{
if(dp[la1][la2][t][i-1]==-1)
continue;
if(i==len)
{
if(t) //相等,最后一位只能是0 1
{
if(dp[0][1][1][len]==-1)
dp[0][1][1][len]=dp[la1][la2][t][len-1];
else
dp[0][1][1][len]+=dp[la1][la2][t][len-1];
dp[0][1][1][len]%=M;
path1[0][1][1][i]=la1;
path2[0][1][1][i]=la2;
path3[0][1][1][i]=t;
}
else // 1 0 前面小于
{
if(dp[1][0][1][len]==-1)
dp[1][0][1][len]=dp[la1][la2][t][len-1];
else
dp[1][0][1][len]+=dp[la1][la2][t][len-1];
dp[1][0][1][len]%=M;
path1[1][0][1][i]=la1;
path2[1][0][1][i]=la2;
path3[1][0][1][i]=t;
}
continue;
}
if(!t) //小于 必须1,0
{
if(dp[1][0][0][i]==-1)
dp[1][0][0][i]=dp[la1][la2][t][i-1];
else
dp[1][0][0][i]+=dp[la1][la2][t][i-1];
dp[1][0][0][i]%=M;
path1[1][0][0][i]=la1;
path2[1][0][0][i]=la2;
path3[1][0][0][i]=t;
}
else //等于 可以继续等于 也可以当前位小于
{
if(dp[0][0][1][i]==-1)
dp[0][0][1][i]=dp[la1][la2][t][i-1];
else
dp[0][0][1][i]+=dp[la1][la2][t][i-1];
dp[0][0][1][i]%=M;
path1[0][0][1][i]=la1;
path2[0][0][1][i]=la2;
path3[0][0][1][i]=t; if(dp[1][1][1][i]==-1)
dp[1][1][1][i]=dp[la1][la2][t][i-1];
else
dp[1][1][1][i]+=dp[la1][la2][t][i-1];
dp[1][1][1][i]%=M;
path1[1][1][1][i]=la1;
path2[1][1][1][i]=la2;
path3[1][1][1][i]=t; if(dp[0][1][0][i]==-1)
dp[0][1][0][i]=dp[la1][la2][t][i-1];
else
dp[0][1][0][i]+=dp[la1][la2][t][i-1];
dp[0][1][0][i]%=M;
path1[0][1][0][i]=la1;
path2[0][1][0][i]=la2;
path3[0][1][0][i]=t;
} }
}
}
else if(sa1[i]=='?')
{
for(int la1=0;la1<=1;la1++)
for(int la2=0;la2<=1;la2++)
{
for(int t=0;t<=1;t++)
{
if(dp[la1][la2][t][i-1]==-1)
continue;
int q=(sa2[i]=='0')?(la2):(la2^1); if(i==len)
{
if(q) //0 1
{
if(t) //等于
{
if(dp[0][1][1][len]==-1)
dp[0][1][1][len]=dp[la1][la2][t][len-1];
else
dp[0][1][1][len]+=dp[la1][la2][t][len-1];
dp[0][1][1][len]%=M;
path1[0][1][1][i]=la1;
path2[0][1][1][i]=la2;
path3[0][1][1][i]=t;
}
}
else // 1 0
{
if(!t) //小于
{
if(dp[1][0][1][len]==-1)
dp[1][0][1][len]=dp[la1][la2][t][len-1];
else
dp[1][0][1][len]+=dp[la1][la2][t][len-1];
dp[1][0][1][len]%=M;
path1[1][0][1][i]=la1;
path2[1][0][1][i]=la2;
path3[1][0][1][i]=t;
}
}
continue;
}
if(!t) //小于 当前必须1 0
{
if(q)
continue;
if(dp[1][0][0][i]==-1)
dp[1][0][0][i]=dp[la1][la2][t][i-1];
else
dp[1][0][0][i]+=dp[la1][la2][t][i-1];
dp[1][0][0][i]%=M;
path1[1][0][0][i]=la1;
path2[1][0][0][i]=la2;
path3[1][0][0][i]=t;
}
else //等于 当前可以等于也可以小于
{
if(dp[q][q][1][i]==-1)
dp[q][q][1][i]=dp[la1][la2][t][i-1];
else
dp[q][q][1][i]+=dp[la1][la2][t][i-1];
dp[q][q][1][i]%=M;
path1[q][q][1][i]=la1;
path2[q][q][1][i]=la2;
path3[q][q][1][i]=t; if(!q)
continue;
if(dp[0][1][0][i]==-1)
dp[0][1][0][i]=dp[la1][la2][t][i-1];
else
dp[0][1][0][i]+=dp[la1][la2][t][i-1];
dp[0][1][0][i]%=M;
path1[0][1][0][i]=la1;
path2[0][1][0][i]=la2;
path3[0][1][0][i]=t; }
}
}
}
else //sa2[i]=='?'
{
for(int la1=0;la1<=1;la1++)
for(int la2=0;la2<=1;la2++)
{
for(int t=0;t<=1;t++)
{
if(dp[la1][la2][t][i-1]==-1)
continue; int p=(sa1[i]=='0')?(la1):(la1^1);
if(i==len)
{
if(p)
{
if(!t)
{
if(dp[1][0][1][len]==-1)
dp[1][0][1][len]=dp[la1][la2][t][len-1];
else
dp[1][0][1][len]+=dp[la1][la2][t][len-1];
dp[1][0][1][len]%=M;
path1[1][0][1][i]=la1;
path2[1][0][1][i]=la2;
path3[1][0][1][i]=t;
}
}
else //p==0
{
if(t)
{
if(dp[0][1][1][len]==-1)
dp[0][1][1][len]=dp[la1][la2][t][len-1];
else
dp[0][1][1][len]+=dp[la1][la2][t][len-1];
dp[0][1][1][len]%=M;
path1[0][1][1][i]=la1;
path2[0][1][1][i]=la2;
path3[0][1][1][i]=t;
}
}
continue;
}
if(!t)
{
if(!p)
continue;
if(dp[1][0][0][i]==-1)
dp[1][0][0][i]=dp[la1][la2][t][i-1];
else
dp[1][0][0][i]+=dp[la1][la2][t][i-1];
dp[1][0][0][i]%=M;
path1[1][0][0][i]=la1;
path2[1][0][0][i]=la2;
path3[1][0][0][i]=t;
}
else
{
if(dp[p][p][1][i]==-1)
dp[p][p][1][i]=dp[la1][la2][t][i-1];
else
dp[p][p][1][i]+=dp[la1][la2][t][i-1];
dp[p][p][1][i]%=M;
path1[p][p][1][i]=la1;
path2[p][p][1][i]=la2;
path3[p][p][1][i]=t; if(p)
continue;
if(dp[0][1][0][i]==-1)
dp[0][1][0][i]=dp[la1][la2][t][i-1];
else
dp[0][1][0][i]+=dp[la1][la2][t][i-1];
dp[0][1][0][i]%=M;
path1[0][1][0][i]=la1;
path2[0][1][0][i]=la2;
path3[0][1][0][i]=t; }
}
}
}
// for(int k=0;k<=1;k++)
// for(int kk=0;kk<=1;kk++)
// printf("dp[%d][%d][0][%d]:%d ",k,kk,i,dp[k][kk][0][i]),printf("dp[%d][%d][1][%d]:%d\n",k,kk,i,dp[k][kk][1][i]);;
}
int ans=0;
int a,b,tmp;
if(dp[0][1][1][len]!=-1)
{
ans=(ans+dp[0][1][1][len])%M;
a=0,b=1,tmp=1;
}
if(dp[1][0][1][len]!=-1)
{
ans=(ans+dp[1][0][1][len])%M;
a=1,b=0,tmp=1;
}
printf("Case #%d:\n",ca);
if(ans==1)
{
sa1[len]=a+'0',sa2[len]=b+'0'; //输出路径
int i=len-1;
while(i>=1)
{
int aa=path1[a][b][tmp][i+1];
int bb=path2[a][b][tmp][i+1];
int tmm=path3[a][b][tmp][i+1];
sa1[i]=aa+'0';
sa2[i]=bb+'0';
a=aa,b=bb,tmp=tmm;
i--;
} //先求出P 和 P+1 然后求出G(p)和G(p+1)
// printf("%s\n%s\n",sa1+1,sa2+1);
sa1[0]=sa2[0]='0';
for(int i=1;i<=len;i++)
{
ans1[i]=(sa1[i]==sa1[i-1])?'0':'1';
ans2[i]=(sa2[i]==sa2[i-1])?'0':'1'; }
ans1[len+1]=ans2[len+1]='\0';
printf("%s\n%s\n",ans1+1,ans2+1); }
else if(ans==0)
printf("Impossible\n");
else
printf("Ambiguous %d\n",ans);
}
return 0;
}
dp-史上最戳最长最臭代码-hdu-4733-G(x)的更多相关文章
- 史上最全的微信小程序代码大全
--------------------- 本文来自 fenxiangjun 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/fenxiangjun/article/d ...
- JMeter 使用 http长连接 |史上最全
疯狂创客圈 Java 高并发[ 亿级流量聊天室实战]实战系列 [博客园总入口 ] 疯狂创客圈(笔者尼恩创建的高并发研习社群)Springcloud 高并发系列文章,将为大家介绍三个版本的 高并发秒杀: ...
- http的长连接和短连接(史上最通俗!)
1.以前的误解 很久之前就听说过长连接的说法,而且还知道HTTP1.0协议不支持长连接,从HTTP1.1协议以后,连接默认都是长连接.但终究觉得对于长连接一直懵懵懂懂的,有种抓不到关键点的感觉. 今天 ...
- 移动端IM开发者必读(二):史上最全移动弱网络优化方法总结
1.前言 本文接上篇<移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”>,关于移动网络的主要特性,在上篇中已进行过详细地阐述,本文将针对上篇中提到的特性,结合我们的实践经 ...
- 史上最全的各种C++ STL容器全解析
史上最全的C++ STL 容器大礼包 为什么\(C++\)比\(C\)更受人欢迎呢?除了\(C++\) 的编译令人感到更舒适,\(C++\)的标准模板库(\(STL\))也占了很重要的原因.当你还在用 ...
- 史上最全的CSP2019复习指南
CSP2019复习指南 知识点(大纲)内容参考于本人博客: 近22年NOIP考点一览 算法 基本算法: 模拟.暴力枚举.排序.贪心.递归.递推.贪心.二分.位运算 这些算法不再在此加以赘述,如有考前还 ...
- 从史上八大MySQL事故中学到的经验
本文列举了史上八大MySQL宕机事件原因.影响以及人们从中学到的经验,文中用地震级数来类比宕机事件的严重性和后果,排在最严重层级前两位的是由于亚马逊AWS宕机故障(相当于地震十级和九级). 一.Per ...
- 【Tips】史上最全H1B问题合辑——保持H1B身份终级篇
[Tips]史上最全H1B问题合辑——保持H1B身份终级篇 2015-04-10留学小助手留学小助手 留学小助手 微信号 liuxue_xiaozhushou 功能介绍 提供最真实全面的留学干货,帮您 ...
- 史上最简单,一步集成侧滑(删除)菜单,高仿QQ、IOS。
重要的话 开头说,not for the RecyclerView or ListView, for the Any ViewGroup. 本控件不依赖任何父布局,不是针对 RecyclerView. ...
随机推荐
- 学习python 一些错误记录
1. TypeError: 'unicode' object is not callable当遇到这样的错误时候, 一般是属性当做方法调用了,比如,selenium 脚本, driver.title ...
- MAC上使用maven打android的包,报错:No Android SDK path could be found. 解决办法
对android工程运行mvn compile出现如下信息: No Android SDK path could be found. You may configure it in the pom u ...
- python 学习笔记 9 -- Python强大的自省简析
1. 什么是自省? 自省就是自我评价.自我反省.自我批评.自我调控和自我教育,是孔子提出的一种自我道德修养的方法.他说:“见贤思齐焉,见不贤而内自省也.”(<论语·里仁>)当然,我们今天不 ...
- 说出x的结果,并解释为什么?
var x = 1; if(function f(){}){ x += typeof f; } x; //x的结果是? x=1undefined 首先是 if表达式的问题 if括号里,不一定非要用== ...
- php部分学习笔记
[web 开发分为]1. 静态web 开发(html 页面) 如果我们的一个页面,始终是一成不变的,则就是属于静态web 开发,一般讲用html 技术就ok2. 动态web 开发 比如: 我们需要发帖 ...
- 游戏中网络数据包和HTTP数据的思考
快下班了,对于这个沙盒类文字游戏,其实考虑的东西还是很多的,服务器的架构,NPC, NPC API的运算,等等等 现在在思考大数据传输,比如背包数据或者拍卖行的商品展示数据在传输的时候的性能问题 目前 ...
- 【Linux指令】使用中学习(一)
sed指令: 应用:对于大文件,比如10G的大文件,我遇到的是导出的数据库.sql文件,想要使用vim修改几乎是不可能的,用sed指令可以在不打开文件的情况下修改文件,下面是一些具体用法 删除文件特定 ...
- 查看oracle数据库的大小和空间使用情况
查看oracle数据库的大小和空间使用情况 (2012-06-19 14:44:30) 转载▼ 标签: 杂谈 分类: oracle 1.查看表空间的使用状况 SELECT upper(f.tables ...
- 《windows程序设计》学习_4:文本输出,加滚动条
//总行数 #define NUMLINES ((int) (sizeof sysmetrics / sizeof sysmetrics [0])) struct { int Index ; TCHA ...
- iOS6和iOS7代码的适配(2)——status bar
用Xcode5运行一下应用,第一个看到的就是status bar的变化.在iOS6中,status bar是系统在处理,应用中不需要考虑这部分,iOS7之后是应用在处理,每个ViewControlle ...