二进制
来源:互联网 发布:淘宝网电动车阳伞 编辑:程序博客网 时间:2024/06/05 11:57
题目
过程
这是上午考试的第四题。当时自己读完题后,看了数据规模,感觉是故意设计的(本来就是嘛),但是又实在没有方法,就只好打了一个两个dfs嵌套的暴力。。结果(猜也能猜出来):WA×5,TLE×5。
正解:dp。(什么?这破题居然能dp?)
思路:首先预处理出所有的情况,然后O(1)输出。
dp数组开成[32][32][32][32][2]大小,f[l][i][j][k][jin]表示Z的长度最大为l、X
枚举l、i、j、k、jin以后,如果情况成立,我们用p、q、r分别枚举X、Y、Z的下一位,若情况仍成立,那么我们就可以进行状态转移。状态转移方程如下:
if(f[l+1][i+p][j+q][k+r][(p+q+jin-r)/2]==-1||f[l][i][j][k][jin]+r*(1<<l)<f[l+1][i+p][j+q][k+r][(p+q+jin-r)/2])f[l+1][i+p][j+q][k+r][(p+q+jin-r)/2]=f[l][i][j][k][jin]+r*(1<<l);
其中,l+1为新生成的Z的长度,i+p、j+q、k+r不必说,(p+q+jin-r)/2为新产生的Z的进位。为什么呢?因为p+q+jin更新了Z,r为新生成的Z的个位,减去r再整除2即为新的Z在二进制下的余数。
其余的请见代码:
#include<cstdio>#include<cstring>#include<iostream>using namespace std;int n,a,b,c,g1,g2,g3,l1,l2,l3,i,len;int f[32][32][32][32][2];void init(int n,int &length,int &ge){ length=ge=0; while(n) { if(n%2) ge++; n>>=1; length++; }}void dp(){ memset(f,-1,sizeof(f)); f[0][0][0][0][0]=0; for(int l=0;l<=30;l++) for(int i=0;i<=30;i++) for(int j=0;j<=30;j++) for(int k=0;k<=30;k++) for(int jin=0;jin<=1;jin++) if(f[l][i][j][k][jin]>=0) for(int p=0;p<=1;p++) for(int q=0;q<=1;q++) for(int r=0;r<=1;r++) if((p+q+jin)%2==r) if(f[l+1][i+p][j+q][k+r][(p+q+jin-r)/2]==-1||f[l][i][j][k][jin]+r*(1<<l)<f[l+1][i+p][j+q][k+r][(p+q+jin-r)/2]) f[l+1][i+p][j+q][k+r][(p+q+jin-r)/2]=f[l][i][j][k][jin]+r*(1<<l);}main(){ freopen("binary.in","r",stdin); freopen("binary.out","w",stdout); dp(); scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d%d%d",&a,&b,&c); init(a,l1,g1); init(b,l2,g2); init(c,l3,g3); len=max(l1,max(l2,l3)); printf("%d\n",f[len][g1][g2][g3][0]); }}
0 0
- 二进制
- 二进制
- 二进制
- 二进制
- 二进制
- 二进制
- 二进制
- 二进制
- 二进制
- 二进制
- 二进制
- 二进制
- 二进制
- 二进制
- 二进制
- 二进制
- 二进制
- 二进制
- 关于c语言自加自减的分析
- 数据操纵语言
- 浅谈simhash及其python实现
- Linux下C开发工具介绍
- java基础- 异常的层次结构
- 二进制
- JZOJ 4777. 【NOIP2016提高A组模拟9.14】灌水
- 携程火车票业务在 React Native 实践中踩过的坑
- 文章标题 POJ 2485 : Highways(最小生成树--kruskal+并查集)
- 使用matlab和c++读取文本数据混合文档
- 收集一些好用的网站
- 我的第一篇博客
- 好用且实用的链式前向星(好像就是邻接表)
- 控制一个高消耗CPU的线程数控制方案