位运算的一种应用 和 hiho1516过河解题报告
初始i=s
每次:i=(i-1) & s
直到i=0
etc.
11000
10000
01000
00000
10000=10001 & 11000
01000=01111 & 11000
00000=00111 & 11000
etc.
11110
11100
11010
11000
10110
10100
10010
10000
01110
01100
01010
01000
00110
00100
00010
00000
证明:
所有i满足 (s & i)==i,
且所有满足 (s & i)==i 的数都出现过
1.
证明:(s & i)==i
因为“i=(i’-1) & s”,
对于i的第t位i(t):
当s(t)=0时,i(t)=_ & 0 = 0
_ & 0 = 0
当s(t)=1时
1 & i(t) = i(t)
所以(s & i)==i成立
2.
证明:
所有满足 (s & i)==i 的数都出现过
对于s中值为0的位 s(t),因为“i=(i’-1) & s”,所以i(t)永远为0
对于s中值位0的位 s(t),因为“i=(i’-1) & s”,所以i(t)永远不会因为s而影响,所以i(t)的值 为(i’-1)的第t位
即“(s & i)==i”相当于原来s中的‘1’组成的数字从11…1到00…0每次减少1的变化,而原来s中的‘0’永远不变
得证
Usage:
共有n个人,当前有m个人可以工作,每个人可以被选或不被选,求出这m个人的所有选择情况(用二进制表示)
Problem:
hiho1516
bfs+状态压缩:
重要的是弄清每次生成新的状态的方法。。。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h> struct node
{
long pos,step,sum;
}q[];
//2^16 * 2(两岸) long n,cond[],g[],num[][];//0为起始岸;1为终止岸;2为船 总数(二进制)
long vis1[],vis2[],vis3;
bool vis[][]; bool judge()
{
long i,j,k;
for (j=;j<;j++)
{
for (i=;i<g[cond[j]];i++)
{
k=num[cond[j]][i];
if (((vis1[k] & cond[j])!=) && ((vis2[k] & cond[j])==))
return false;
} // for (i=0;i<n;i++)
// if (((cond[j]>>i) & i)!=1)
// if ( ((vis1[i] & cond[j])!=0) && ((vis2[i] & cond[j])==0) )
// return false;
}
if ((cond[] & vis3)==)
return false;
return true;
} int main()
{
long m,a,b,c,x,y,head,tail,i,j,k,total,pos,pos_,sum,step,mul[];
scanf("%ld%ld",&n,&m);
mul[]=;
for (i=;i<=n;i++)
mul[i]=mul[i-]<<;
total=(<<n)-;
for (i=;i<=total;i++)
{
g[i]=;
j=i;
k=;
while (j>)
{
if ((j & )==)
{
num[i][g[i]]=k;
g[i]++;
}
k++;
j=j>>;
}
} scanf("%ld%ld%ld",&a,&b,&c);
for (i=;i<n;i++)
{
vis1[i]=;
vis2[i]=;
}
vis3=;
for (i=;i<=a;i++)
{
scanf("%ld%ld",&x,&y);
vis1[x]+=<<y;
}
for (i=;i<=b;i++)
{
scanf("%ld%ld",&x,&y);
vis2[y]+=<<x;
}
for (i=;i<=c;i++)
{
scanf("%ld",&x);
vis3+=<<x;
}
for (i=;i<;i++)
for (j=;j<;j++)
vis[i][j]=true; head=;
tail=;
q[].pos=;
q[].step=;
q[].sum=total;
vis[total][]=false; while (head<tail)
{
head++; //另外的优化:
//如果在左边,则送尽量多的人到右边
//如果在右边,则送尽量少的人到左边 //编写程序的简单性:两岸做法的对称性 (Same),从而合二为一 pos=q[head].pos;
pos_=pos ^ ;
sum=q[head].sum;
step=q[head].step+;
//不必取0,前后必会发生变化
for (i=sum;i>;i=(i-) & sum)
if (g[i]<=m)
{
cond[]=i;
cond[pos]=sum-i;
cond[pos_]=total-cond[pos]; if (vis[cond[pos_]][pos_]==true && judge()==true)
{
// printf("%ld %ld\n",cond[pos_],pos_);
if (pos_== && cond[]==total)
{
printf("%ld\n",step);
return ;
}
tail++;
q[tail].pos=pos_;
q[tail].step=step;
q[tail].sum=cond[pos_];
vis[cond[pos_]][pos_]=false;
}
}
}
printf("-1\n");
return ;
}
/*
位运算的优势:
1.相比正常运算极快的运行速度
2.存储的减少
3.程序编写的简单(和不容易出错)
*/
位运算的一种应用 和 hiho1516过河解题报告的更多相关文章
- n&m位运算
在C/C++语言里,&代表取地址或者“位与”运算 1.取变量的地址:&变量名,这将获得该变量的地址,例:int a = 1, &p = a. 2.进行位与运算,格式是:变量1& ...
- C语言位运算+实例讲解(转)
按位或 按位与 按位异或 按位取反 左移右移 C语言位运算 有6种: &, | , ^(亦或), >(右移). 注意:参与位运算的元素必须是int型或者char型,以补码形式出现. 按位 ...
- js中的位运算
按位运算符是把操作数看作一系列单独的位,而不是一个数字值.所以在这之前,不得不提到什么是"位": 数值或字符在内存内都是被存储为0和 1的序列,每个0和1被称之为1个位,比如说10 ...
- C#枚举中的位运算权限分配浅谈
常用的位运算主要有与(&), 或(|)和非(~), 比如: 1 & 0 = 0, 1 | 0 = 1, ~1 = 0 在设计权限时, 我们可以把权限管理操作转换为C#位运算来处理. 第 ...
- Java位运算经典实例
一 源码.反码.补码 正数的源码.反码.补码相同,例如5: 5的源码:101 5的反码:101 5的补码:101 负数的源码.反码.补 ...
- EF架构~为分组添加位运算聚合方法
回到目录 我们知道在Linq里的分组groupby可以对集合中一个或者多个字段进行分组,并对其中一个属性进行聚合,而Linq为我们提供了多种聚合方法,由aver,sum,count等,而在大叔权限体系 ...
- leetcode - 位运算题目汇总(下)
接上文leetcode - 位运算题目汇总(上),继续来切leetcode中Bit Manipulation下的题目. Bitwise AND of Numbers Range 给出一个范围,[m, ...
- 深入理解计算机系统(2.2)---布尔代数以及C语言上的位运算
布尔代数上的位运算 布尔代数是一个数学知识体系,它在0和1的二进制值上演化而来的. 我们不需要去彻底的了解这个知识体系,但是里面定义了几种二进制的运算,却是我们在平时的编程过程当中也会遇到的.这四种运 ...
- 关于PHP位运算的简单权限设计
写在最前面 最近想写一个简单的关于权限处理的东西,之前我也了解过用二进制数的位运算可以出色地完成这个任务.关于二进制数 的位运算,常见的就是“或.与.非”这三种简单运算了,当然,我也查看了下PHP手册 ...
随机推荐
- WPF的DataTrigger绑定自身属性
原文:WPF的DataTrigger绑定自身属性 <DataTrigger Binding="{Binding RelativeSource={RelativeSource self} ...
- 蓝牙inquiry流程之Advertising Report
setting 界面开始搜索的时候,通常也会同时进行le scan,这一点在inquiry流程之命令下发中已经讲述.此篇文章主要是分析一下对于controller 搜索到的广播包的处理.这里以Andr ...
- shell变量常用方法
变量之数组操作: 参考网址:http://www.jb51.net/article/55253.htm #直接赋值 [root@local-]=chengd [root@local-]=xrd [ro ...
- CS50.5
函数,全局变量,参数,返回值. 1,类型转换. 各种数据类型进行转换 2,API函数 应用程序编程接口. application programming interface 写写随笔吧,先说计算机.. ...
- 使用python处理百万条数据分享(适用于java新手)
1.前言 因为负责基础服务,经常需要处理一些数据,但是大多时候采用awk以及java程序即可,但是这次突然有百万级数据需要处理,通过awk无法进行匹配,然后我又采用java来处理,文件一分为8同时开启 ...
- [转载]windows下PHP + Nginx curl访问本地地址超时卡死问题的解决方案
原因: windows 下 nginx+php环境,不支持并发. 解决方案: 1.在配置nginx vhost时,需要同时运行的网站设置不同的fastcgi_pass的端口号 server { ser ...
- Js_图片切换左右点击
<!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" content=&q ...
- 2、Arx二次开发创建第一个应用程序
一.本节课程 Arx二次开发创建第一个应用程序 二.本节要讲解的知识点 1.手动创建ARX的应用的步骤. 2.应用向导创建ARX应用程序的步骤. 三.具体内容 1.需求:创建一个Hello World ...
- DRF02
1. 视图 Django REST framwork 提供的视图的主要作用: 控制序列化器的执行(检验.保存.转换数据) 控制数据库查询的执行 1.1. 请求与响应 1.1.1 Request RES ...
- 老李的blog使用日记(3)
匆匆忙忙.碌碌无为,这是下一个作业,VS,多么神圣高大上,即使这样,有多少人喜欢你就有多少人烦你,依然逃不了被推销的命运,这抑或是它喜欢接受的,但是作为被迫接受者,能做的的也只有接受,而已. 既来之则 ...