Hdu4712 Hamming Distance ---- 多向BFS
来源:互联网 发布:知乎 用的什么编辑器 编辑:程序博客网 时间:2024/06/05 16:57
题目链接:HDU 4712
看评论里面很多人都是用随即算法过的 在这里贴一个非随即算法的解法
题意:给你n个(n<=1e5)数a0~a(n-1)(ai<(1<<20)) 要你求这n个数中转化为二进制后任意两个数中最小的汉明距离 \\ wiki百科:汉明距离
例如:a0 = 00000000010000000000 a1 = 00000000000000000001 a2 = 00000000000000000011
则答案为1 , 因为 a1^a2 = 00000000000000000010 其中1的个数为1,则答案为1
思路:
先说下随即算法的思路:首先当n比较小的时候,直接暴力枚举每两个数,求最小的汉明距离即可;当n比较大时,每次直接随即选出两个数a,b,求出汉明距离选取最小的即可。
因为ai<(1<<20),说明最终解一定<=20,解的范围很小,所以随即算法成功的几率还是很高的。
======================================================================================
接下来说说非随即算法(全是个人独立想出的哦)
首先要利用汉明距离的一个性质,二进制字符串的汉明距离也等于 n 维超正方体两个顶点之间的曼哈顿距离,其中n 是两个字串的长度。
我们先令(a,b)表示二进制字符a,b的汉明距离!!
怎么解释那个性质呢,就是比如有a,b,c三个二进制字符,其中(a,b)==(b,c)==1,那么(a,c) = (a,b)+(b,c) = 2
再加入一个d,假设(c,d)==1,且(d,a)!=1且(d,b)!=1,那么(d,a) = (a,b)+(b,c)+(c,d) = 3; (d,b) = (b,c)+(c,d) = 2;
(对于这个性质我一开始也是猜测,然后写了个小程序简单验证了一下,再后来仔细看汉明距离的wiki百科的时候才发现上面写着有。。。
怪不得题目上面一开始就表明了(From WIKI)。。。 )
有了这个性质接下来的事情就比较简单了
因为a<(1<<20),所以先把这(1<<20)个数当成(1<<20)个结点,然后把其汉明距离为1的结点连接起来,把边的长度设为1,
这样两个数的汉明距离即为这个图上两点间的最短路长度
如此一来,我们就可以把给出的n个数当成n个起点,然后在图上进行搜索,搜出任意两起点间最短的距离
搜索的方法就类似于多向BFS,具体的实现见代码
PS:多向BFS在搜索时,搜索到一个解并不能马上返回,需要把当前这一层的结点搜索完毕,然后返回一个最优值
比如下面这个图
可以尝试模拟一下,其中1,2,3表示搜索起点,当搜索到4号结点的时候,如果先行搜索红色边的话,则返回值是4,而正确解应该是3
下面贴代码
#include <iostream>#include <cstring>#include <stdio.h>#include <math.h>#include <fstream>#include <algorithm>#include <stack>#include <vector>#include <queue>using namespace std;#define REP(i,n) for(int i=0;i<(n);i++)#define FOR(i,j,k) for(int i=j;i<=(k);i++)#define ll long long#define base 20#define maxn (1<<base)+10/*ifstream fin("1");#define cin fin*/int a[100009],n;int Hash(char c){ if(c>='0'&&c<='9') return c-'0'; return 10+c-'A';}void Input(int k){ char s[7]; cin >> s; int st = 0; REP(i,5) { st *= 16; st += Hash(s[i]); } a[k] = st;}int dis[maxn],color[maxn];//dis表示距离,color相当于把从每个起点开始的搜索路径染色queue <int> q;int Solve(){ while(!q.empty()) q.pop(); memset(color,-1,sizeof(color)); memset(dis,-1,sizeof(dis)); REP(i,n){ if(dis[a[i]] != -1) return 0; dis[a[i]] = 0; color[a[i]] = i; q.push(a[i]); } int ans = 2e9,floor = 2e9; // ans 是答案 floor表示的是限定得到解的层数 while(!q.empty()){ int u = q.front(); q.pop(); REP(i,base){ int v = (u^(1<<i)); if(dis[v] == -1){ dis[v] = dis[u] + 1; color[v] = color[u]; // 只有当v的层数小于floor 才将其加入待搜队列 if(dis[v] <= floor) q.push(v); } else if(dis[v] != -1){ if(color[v] == color[u]) continue; // 颜色相同则直接忽略 // return dis[v]+dis[u]+1; 直接返回是错误的!!! ans = min(ans,dis[v]+dis[u]+1); floor = min(floor,dis[u]); } } } return ans;}int main(){ int test; cin >> test; while(test --){ cin >> n; memset(a,-1,sizeof(a)); REP(i,n) Input(i); cout << Solve() << endl; }}
- Hdu4712 Hamming Distance ---- 多向BFS
- hdu4712 Hamming Distance
- HDU4712-----Hamming Distance------超级大水题
- hdu 4712 Hamming Distance bfs
- Hamming Distance
- hamming distance
- hamming distance
- Hamming Distance
- Hamming Distance
- Hamming Distance
- Hamming Distance
- Hamming Distance
- Hamming Distance
- Hamming Distance
- Hamming distance
- Hamming Distance
- Hamming Distance
- hamming distance
- NET多线程编程(14)——用C#实现蜘蛛/爬虫程序的多线程控制
- 深入了解scanf()/getchar()和gets()/cin等函数
- ASP.NET MVC 入门4、Controller与Action
- [STAThread]的含义
- SQL基础-->层次化查询(START BY ... CONNECT BY PRIOR)
- Hdu4712 Hamming Distance ---- 多向BFS
- 详细讲解C#的多线程能力
- MySQL建立新用户&授权
- grails 205—项目实战F
- 免费调查问卷 调查问卷投票系统
- ubuntu12.04 编译安装libev
- 多个div在同一行显示
- ubuntu13.04电信宽带上网,安装影视播放器
- iOS 扩展机制category与associative