hduoj 4712 Hamming Distance 2013 ACM/ICPC Asia Regional Online —— Warmup
http://acm.hdu.edu.cn/showproblem.php?pid=4712
Hamming Distance
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 1610 Accepted Submission(s): 630
2
12345
54321
4
12345
6789A
BCDEF
0137F
7
分析:
输入n个数,用十六进制的方式输入的,任意选择其中的两个数进行异或,求异或后的数用二进制表示后1的个数最小的是多少?(n<=100000)
这题看了解题报告,大家都说用随机算法,试过了,随机100000次就过了,50000次都不行,但还是不懂这样怎么可以,唯一的解释就是这个值域也就是结果一共只有21个,
得出正确的结果的可能性很大,但是并不能100%保证结果是对的。无语第一次碰见这种算法。
首先,算汉明距离就是二进制异或以后的1的个数,统计1的个数用x&=x-1很快很神奇。
用if(x&1) {count++; x>>=1;} 在位数比较多的时候会慢一些。
然后就是看题解学到的神奇的“随机”! 来取到“任意的两个” 1w次wa,但是10w次就不会,20组testcase ,不会超时。
队友用随机函数在hduoj上交了五次(WA了4次)A了。也是醉啦 ,,,
AC代码:
- #include<iostream>
- #include<cstring>
- #include<string>
- #include<cmath>
- #include<cstdio>
- #include<algorithm>
- using namespace std;
- int a[];
- int main()
- {
- int tes,i,j,k,res,ans;
- scanf("%d",&tes);
- while(tes--)
- {
- int n;
- scanf("%d",&n);
- for(i=;i<n;i++)
- scanf("%X",&a[i]); //16进制读取
- res=; //结果初始为最大20
- for(i=;i<=;i++)
- {
- j=rand()%n; //随机函数
- k=rand()%n;
- if(j==k)
- continue;
- ans=;
- int tmp=a[j]^a[k]; //抑或
- while(tmp) //抑或算1的个数,保存到ans中
- {
- if(tmp&)
- ans++;
- tmp>>=;
- }
- if(ans<res)
- res=ans;
- }
- cout<<res<<endl;
- }
- return ;
- }
网上贴的都是随机算法做的,下面找了一个非随机的思想。
题意:给你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
AC代码:
- #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[],n;
- int Hash(char c){
- if(c>=''&&c<='') return c-'';
- return +c-'A';
- }
- void Input(int k){
- char s[];
- cin >> s;
- int st = ;
- REP(i,) {
- st *= ;
- 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,-,sizeof(color));
- memset(dis,-,sizeof(dis));
- REP(i,n){
- if(dis[a[i]] != -) return ;
- dis[a[i]] = ;
- 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^(<<i));
- if(dis[v] == -){
- dis[v] = dis[u] + ;
- color[v] = color[u];
- // 只有当v的层数小于floor 才将其加入待搜队列
- if(dis[v] <= floor) q.push(v);
- }
- else if(dis[v] != -){
- if(color[v] == color[u]) continue; // 颜色相同则直接忽略
- // return dis[v]+dis[u]+1; 直接返回是错误的!!!
- ans = min(ans,dis[v]+dis[u]+);
- floor = min(floor,dis[u]);
- }
- }
- }
- return ans;
- }
- int main(){
- int test;
- cin >> test;
- while(test --){
- cin >> n;
- memset(a,-,sizeof(a));
- REP(i,n) Input(i);
- cout << Solve() << endl;
- }
- }
hduoj 4712 Hamming Distance 2013 ACM/ICPC Asia Regional Online —— Warmup的更多相关文章
- hduoj 4710 Balls Rearrangement 2013 ACM/ICPC Asia Regional Online —— Warmup
http://acm.hdu.edu.cn/showproblem.php?pid=4710 Balls Rearrangement Time Limit: 6000/3000 MS (Java/Ot ...
- hduoj 4706 Herding 2013 ACM/ICPC Asia Regional Online —— Warmup
hduoj 4706 Children's Day 2013 ACM/ICPC Asia Regional Online —— Warmup Herding Time Limit: 2000/1000 ...
- hduoj 4707 Pet 2013 ACM/ICPC Asia Regional Online —— Warmup
http://acm.hdu.edu.cn/showproblem.php?pid=4707 Pet Time Limit: 4000/2000 MS (Java/Others) Memory ...
- hduoj 4708 Rotation Lock Puzzle 2013 ACM/ICPC Asia Regional Online —— Warmup
http://acm.hdu.edu.cn/showproblem.php?pid=4708 Rotation Lock Puzzle Time Limit: 2000/1000 MS (Java/O ...
- hduoj 4715 Difference Between Primes 2013 ACM/ICPC Asia Regional Online —— Warmup
http://acm.hdu.edu.cn/showproblem.php?pid=4715 Difference Between Primes Time Limit: 2000/1000 MS (J ...
- hduoj 4706 Children's Day 2013 ACM/ICPC Asia Regional Online —— Warmup
http://acm.hdu.edu.cn/showproblem.php?pid=4706 Children's Day Time Limit: 2000/1000 MS (Java/Others) ...
- 2013 ACM/ICPC Asia Regional Online —— Warmup
1003 Rotation Lock Puzzle 找出每一圈中的最大值即可 代码如下: #include<iostream> #include<stdio.h> #inclu ...
- HDU 4714 Tree2cycle(树状DP)(2013 ACM/ICPC Asia Regional Online ―― Warmup)
Description A tree with N nodes and N-1 edges is given. To connect or disconnect one edge, we need 1 ...
- HDU 4749 Parade Show 2013 ACM/ICPC Asia Regional Nanjing Online
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4749 题目大意:给一个原序列N,再给出一个序列M,问从N中一共可以找出多少个长度为m的序列,序列中的数 ...
随机推荐
- X5学习笔记—给单元格添加颜色
设置grid某一个单元格的颜色 可以用dhtmlxgrid的原生态方法 setCellTextStyle (row_id, ind, styleString) 参数: rowid:行id cellin ...
- [have_fun] 好玩哒小游戏又来啦
联机贪吃蛇,相互厮杀,试一下吧! http://splix.io/
- javascript 原生事件综合查询
click() 对象.click() 使对象被点击. closed 对象.closed 对象窗口是否已关闭true/false clearTimeout(对象) 清除已设置的setTimeout对象 ...
- c# ToString() 用法
string tempa = Convert.ToString(31, 2);//将10进制数31转换为2进制字符串. string strNums = int.Parse(tempa).ToStri ...
- cdecl和stdcall调用约定-汇编演示
. .model flat, stdcall .stack ExitProcess PROTO, dwExitCode:DWORD .data val2 sdword result dword ? . ...
- IE中的fireEvent和webkit中的dispatchEvent
拿浏览器的click事件来说: 在IE浏览器中如果一个element没有注册click事件,那么直接调用的话会出现异常!当然如果你注册了没有什么可说的. 那么如果使用fireEvent来处理,clic ...
- To do
小事{ android values public.xml 树.图的所有遍历方式和优劣 } 大事{ 通读android所有官网文档. android多dex多res开发框架. java AOT(and ...
- js实现表格中不同单元格内容的替换(不同浏览器的节点属性兼容问题)
-------> 效果:点击右下角单元格,左下角单元格内容被替换成和左上角相同,如上图所示. 实现方式:分别获取各个节点,并将左边节点的内容修改成左上方节点的内容. 代码: 注意的地方: ...
- c#中栈和堆的理解
之前对栈(stack)和堆(heap)的认识很模糊,今天看了一篇关于堆栈的文章<译文---C#堆VS栈>后,仿佛有种拨开云雾见青天的感觉,当然只是一些浅显的理论的认识,这里做一些简单的记录 ...
- 如何查看mac系统是32位还是64位的操作系统
(一)点击工具栏左上角点击 (苹果Logo)标志,关于本机 --> 更多信息 --> 系统报告 -->(左侧栏中)软件 (二)打开终端,输入命令 uname -a 回车 x8 ...