bitset 入门——HDU 5036,HDU 5313,HDU 4920,POJ 2443
来源:互联网 发布:linux u盘启动 windows 编辑:程序博客网 时间:2024/06/02 21:15
STL的bitset可以比较方便的实现一些用到位运算技巧的算法,而且在空间复杂度和时间复杂度上比bool数组好很多,(虽然现在还是不知道bitset.count()的复杂度到底是多少),有一些题目可以用位运算优化的就可以用到它。
A - Explosion HDU - 5036
有很多门,门内有不定量的其他门的钥匙,你有对应的钥匙才能打开对应的门,当你没有任何钥匙时,会随机暴力打开某一扇没开的门,问暴力开门的次数的期望。
可以通过计算每一扇门被暴力打开的概率来计算总次数的期望,先处理出每一扇门被打开后不再暴力开门可以直接或间接获得打开哪些门,就可以处理出每扇门被打开的方案数量(包括暴力打开这扇门),所以概率就是1/方案数,用bitset的按位与进行处理。
#include <bits/stdc++.h>using namespace std;const int maxn=1005;int n;bitset<maxn> p[maxn];int main(){ int T,a,b; int cas=0; scanf("%d",&T); while(T--){ cas++; scanf("%d",&n); for(int i=0;i<n;i++)p[i].reset(),p[i][i]=1; for(int i=0;i<n;i++){ scanf("%d",&a); while(a--){ scanf("%d",&b); p[i][--b]=1; } } for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ if(p[j][i]){ p[j]|=p[i]; } } } double ans=0; for(int i=0;i<n;i++){ int cc=0; for(int j=0;j<n;j++){ if(p[j][i])cc++; } ans+=1.0/cc; } printf("Case #%d: ",cas); printf("%.5lf\n",ans); } return 0;}
B - Bipartite Graph HDU - 5313
把一张可能不完整的二分图加边变成完整的二分图能加的最多边数。
满足二分图,可加的边就是两个点集的任意点对,所以对于n各点,点的分集合方案越接近n/2就总边数就越大,所以对于原图的每一个联通块求二份点集,问题就转化成了每一个联通块的两个点集如何组合,使得最终两个点集的点数量最接近n/2,dp转移复杂度比较高,使用位移操作可以降低一个n的复杂度。
#include<bits/stdc++.h>using namespace std;const int maxn=10015;const int maxe=300005;int n,m;struct edge{ int to,nxt;}e[maxe];int head[maxn];int tot;void adde(int u,int v){ e[tot].to=v; e[tot].nxt=head[u]; head[u]=tot++;}bitset<maxn> dp;int cor[maxn];int cc[2];void bitpart(int cnt,int color){ cc[color-1]++; cor[cnt]=color; for(int i=head[cnt];i!=-1;i=e[i].nxt){ int v=e[i].to; if(cor[v]==0){ bitpart(v,3-color); } }}int main(){ int T,a,b; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); dp.reset(); memset(head,-1,sizeof(head)); memset(cor,0,sizeof(cor)); tot=0; for(int i=0;i<m;i++){ scanf("%d%d",&a,&b); adde(a,b); adde(b,a); } dp[0]=1; for(int i=1;i<=n;i++){ if(cor[i]==0){ cc[0]=cc[1]=0; bitpart(i,1); dp=(dp<<cc[0])|(dp<<cc[1]); } } int ans=0; for(int i=0;;i++){ if(dp[n/2-i]){ ans=n/2-i; break; } } ans=ans*(n-ans)-m; printf("%d\n",ans); } return 0;}
C - Matrix multiplication HDU - 4920
矩阵乘法模3;
根据运算性质现对原矩阵求模,变成两个只有0,1,2的矩阵,根据矩阵运算性质,c[i][j]=sigma(a[i][k]*b[k][j]),对于0,1,2这三个数字,只有1*1,1*2,2*1,2*2会对mod3答案产生贡献,用bieset分别统计a矩阵每行为1,2的状态和b矩阵每列的状态,然后使用按位与和.count()运算统计答案。
#include<bits/stdc++.h>using namespace std;const int maxn=805;const int maxe=300005;int n,m;bitset<maxn> a[maxn][3],b[maxn][4];int getans(int i,int j){ int aa=(a[i][1]&b[j][1]).count(); int bb=(a[i][1]&b[j][2]).count(); int cc=(a[i][2]&b[j][1]).count(); int dd=(a[i][2]&b[j][2]).count(); return (aa+bb*2+cc*2+dd)%3;}int main(){ int x; while(~scanf("%d",&n)){ for(int i=0;i<n;i++){ a[i][0].reset(),a[i][1].reset(),a[i][2].reset(); b[i][0].reset(),b[i][1].reset(),b[i][2].reset(); } for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ scanf("%d",&x); a[i][x%3][j]=1; } } for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ scanf("%d",&x); b[j][x%3][i]=1; } } for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ printf("%d",getans(i,j)); if(j<n-1)printf(" "); } printf("\n"); } } return 0;}
D - Set Operation POJ - 2443
给定多个集合,让你判断数字i和j是否同时存在于这里面的某个集合中。
为每一个数字单独开一个bitset记录哪些集合里有这个数字,然后对于任意询问i和j,将bitset i和 bitset j 按位与,便可得出是否有两个集合同时有这个数字。
#include<cstdio>#include<bitset>using namespace std;const int maxn=10005;const int maxm=1005;int n,m,q;bitset<maxm> p[maxn];int main(){ int a,b,c; scanf("%d",&n); for(int i=0;i<maxn;i++)p[i].reset(); for(int i=0;i<n;i++){ scanf("%d",&a); while(a--){ scanf("%d",&b); p[b][i]=1; } } scanf("%d",&q); while(q--){ scanf("%d%d",&a,&b); bool f=0; if((p[a]&p[b]).count())printf("Yes\n"); else printf("No\n"); } return 0;}
- bitset 入门——HDU 5036,HDU 5313,HDU 4920,POJ 2443
- hdu 5036 概率+bitset
- hdu-Bitset
- HDU——2051——Bitset
- HDU 5036 (STL之bitset)
- HDU 5036 Explosion (bitset + DP)
- HDU 4920 Matrix multiplication(bitset)
- Hdu 2051 - Bitset
- HDU 2051 Bitset
- HDU 2051 - Bitset
- hdu-2501-Bitset
- HDU 2051 Bitset
- HDU 2051 Bitset
- hdu 2051 Bitset(水题)
- HDU 2051 Bitset
- HDU 2051 Bitset
- Bitset HDU 2051
- HDU 2051 Bitset
- 问题
- js设计模式和实践4
- 当一个线程进入一个对象的一个synchronized方法后,其他线程是否可进入此对象的其他方法?
- nginx 隐藏index.php
- printf 应用
- bitset 入门——HDU 5036,HDU 5313,HDU 4920,POJ 2443
- 乱序字符串
- LoadRunner录制手机APP脚本
- python 动态调用模块内的函数
- 静态代码块、构造代码块和构造方法的执行顺序
- 需求实现:点击用户评论列表项,弹出输入法并进行编辑回复功能
- ip子网划分实例
- webpack入口起点
- 经历与经验