Gym
来源:互联网 发布:淘宝女装货源 编辑:程序博客网 时间:2024/05/16 12:22
题意:
给你n个长度为k的01串,让你构造一个串,让这个串和其他各个串相同位置上相同字符的总数的最大值最小。
(k <= 20)
思路:
首先我们最朴素的想法就是暴力枚举该串然后和n个串维护最大值最小.当然这复杂度肯定gg.
那么我们可以从反面来考虑,因为同是二进制数所以我们要构造的那个串肯定都可以由给定的这n个串经过某几位的变换得到.而且观察到两个串之间的value仅仅是相同的几位.也就是说构造的串和这n个串肯定有几位不同.
那么我们可以首先将这n个串加入队列,然后进行bfs变换某几位.那么变换位数越多那么得到的value就越小.
另外这个过程我们必须要维护该二进制第一次被n个串中的某个串变换到所需要变得位数。这是因为我们构造话不好找到中间点,即不知道何时才是最优解所以我们必须要整个过程来维护他.根据bfs的性质,一个串最早可以变换到另一个串,说明他们之间剩下的相同位数多,得到的value大,而其他串要之后才能得到该串说明位数相同的少得到的分数也少,这样就满足我们找到的一个最大值一定满足和当前串最大和其余的最少.
综上,这个过程我们直接维护整个过程中变换次数最多得到的那个串即可.(因为变换次数越多,不同位数越多相同位数越少从而保证最大值越小,PS: 这里通过异或每次使一位变得不同)
#include<bits/stdc++.h>using namespace std;const int maxn = 1e6+1e5+5;struct node{ int num; int step; node(int x = 0,int y = 0) { num = x; step = y; }};int n,k;int ans,ma;bool vis[maxn];void bfs(){ queue<node>Q; memset(vis,0,sizeof vis); while(!Q.empty()) Q.pop(); for(int i = 1;i <= n;++i) { int x; int cur = 0; for(int j = 0;j < k;++j) { scanf("%1d",&x); if(x == 1) cur |= (1 << j); } Q.push(node(cur,0)); vis[cur] = 1; } while(!Q.empty()) { node q = Q.front(); Q.pop(); for(int j = 0;j < k ;++j) { node p; p.num = q.num ^ (1 << j); if(vis[p.num]) continue; p.step = q.step + 1; if(ma < p.step) { ma = p.step; ans = p.num; } Q.push(p); vis[p.num] = 1; } } int len = 0; while(ans) { printf("%d",ans & 1); ans >>= 1; len++; } while(len < k) { printf("0"); len++; } puts(""); return ;}int main(){ while(~scanf("%d %d",&n,&k)) { ans = 0; ma = 0; bfs(); } return 0;}
阅读全文
0 0
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- GTP(GPRS隧道协议)
- <学习html>第三天笔记-链接标签;锚点定位、<base />标签;遇到标签之间关系的问题及解决方法
- [51Nod 1920] 空间统计学
- opencv3实现简单的数字图像识别(KNN)
- Hibernate4 更新删除
- Gym
- 网络编程
- 快速排序(Quick-Sort)
- VS2013+QT+OPENGL+Eigen+Cmake配置方法
- C#中Socket通信用法实例详解
- 分治法,贪心算法,动态规划算法总结(斯坦福算法课Algorithms:Design and Analysis Part2)
- [KMP fail树] BZOJ3670: [Noi2014]动物园
- Eclipse中创建新的Spring Boot项目
- 自己动手实现一个mvvm库