位运算的一种应用 和 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手册 ...
随机推荐
- 列表生成式+过滤器(filter)+映射(map)+lambda总结
这些都是python的特色,不仅强大,而且好用,配合起来使用更是无敌. 零.lambda lambda用于产生一个匿名表达式,组成部分为:lambda + ‘函数表达式’ ‘函数表达式’由一个冒号加上 ...
- FormData 数据转化为 json 数据
两种方法 <!-- 实例:将 FormData 转化为 json --> <meta charset="utf-8"/> <form enctype= ...
- SQL Server 常用内置函数
本文用于收集在运维中经常使用的系统内置(built-in)函数,持续整理中 一,常用Metadata函数 1,查看数据库的ID和Name db_id(‘DB Name’),db_name('DB ID ...
- 机器视觉及图像处理系列之一(C++,VS2015)——搭建基本环境
自<人脸识别>系列发布至今,已一年多矣,期间除答复些许同好者留言外,未再更新文,盖因项目所迫,不得已转战它途,无暇.无料更博耳.其时,虽人已入项目中,然终耿怀于人脸识别方案之谬.初,写此文 ...
- 【转】Cocos2d-x 3.x基础学习: 总结数学类Vec2/Size/Rect
转载:http://www.taikr.com/article/1847 在Cocos2d-x 3.x中,数学类Vec2.Size.Rect,是比较常用的类.比如设置图片位置,图片大小,两图片的碰撞检 ...
- live555学习(一)通读Makefile编译live555
live555学习(一)通读Makefile编译live555 live555 编译live555 学习开源 live555学习(一)通读Makefile编译live555 前言 live555简介 ...
- PAT甲题题解-1058. A+B in Hogwarts (20)-大水题
无语,这种水题还出,浪费时间,但又不得不A... #include <iostream> #include <cstdio> #include <algorithm> ...
- 2-Nineteenth Scrum Meeting-20151219
任务安排 成员 今日完成 明日任务 闫昊 写完学习进度记录的数据库操作 请假(数据库) 唐彬 和服务器老师交流讨论区后台接口 请假(数据库) 史烨轩 尝试使用downloadmanager对noti ...
- 《Linux内核分析》第四周学习笔记
<Linux内核分析>第四周学习笔记 扒开系统调用的三层皮(上) 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.c ...
- c# dataGridView 表头格式设置不管用
解决办法: EnableHeaderVisualStyles设为false