BAPC2014 K&&HUNNU11591:Key to Knowledge(中途相遇法)
来源:互联网 发布:知客是什么意思 编辑:程序博客网 时间:2024/06/06 05:26
题意:
有N个学生,有M题目
然后对应N行分别有一个二进制和一个整数
二进制代表该同学给出的每道题的答案,整数代表该同学的答案与标准答案相符的个数
要求判断标准答案有几个,如果标准答案只有一种,则输出标准答案
思路:
很容易想到状态压缩,但是很明显1<<30纯粹的状压是会超时的,那么我们可以优化一半,变成1<<15
也就是说,对于一个串,我们分半处理
首先处理前一半,讨论前一半与标准答案相符的状况,然后再讨论后半串,看与标准答案相符的情况能不能与前一半相匹配,从而算出答案
#include <iostream>#include <stdio.h>#include <string.h>#include <stack>#include <queue>#include <map>#include <set>#include <vector>#include <math.h>#include <bitset>#include <algorithm>#include <climits>using namespace std;#define ls 2*i#define rs 2*i+1#define UP(i,x,y) for(i=x;i<=y;i++)#define DOWN(i,x,y) for(i=x;i>=y;i--)#define MEM(a,x) memset(a,x,sizeof(a))#define W(a) while(a)#define gcd(a,b) __gcd(a,b)#define LL long long#define ULL unsigned long long#define N 100005#define INF 0x3f3f3f3f#define EXP 1e-8#define rank rank1const int mod = 1000000007;int t,n,m;char str[50][50];int a[50];LL num[50][2];int hsh[1<<16]= {0};int main(){ int i,j,k; for(i = 0; i<(1<<16); i++)//hsh记录1的个数 { t = i; while(t) { hsh[i]+=t%2; t/=2; } } scanf("%d",&t); while(t--) { LL ans = 0; map<LL,int> cnt; map<LL,int> state; scanf("%d%d",&n,&m); for(i = 0; i<n; i++) { scanf("%s%d",str[i],&a[i]); num[i][0]=num[i][1] = 0; for(j = 0; j<m/2; j++)//记录前一半的2进制状态 num[i][0] = num[i][0]*2+(str[i][j]-'0'); for(j = m/2; j<m; j++)//记录后一半的2进制状态 num[i][1] = num[i][1]*2+(str[i][j]-'0'); } //前半部的处理 int s = m/2; for(i = 0; i<(1<<s); i++) { LL tem = 0; for(j = 0; j<n; j++) { k = hsh[i^num[j][0]];//与答案不相同的个数 if(s-k>a[j]) break; tem = tem*30+s-k;//30进制存状态 } if(j==n) { cnt[tem]++;//该状态有几种 state[tem] = i; } } s = m-s;//后一半 int s1,s2; for(i = 0; i<(1<<s); i++) { LL tem = 0; for(j = 0; j<n; j++) { k = hsh[i^num[j][1]]; if(s-k>a[j]) break; tem = tem*30+a[j]-(s-k);//找回前一半的状态 } if(j==n&&cnt[tem]) { ans+=cnt[tem]; s1 = state[tem]; s2 = i; } } if(ans==1) { stack<int> Q; for(i = 0; i<s; i++) { Q.push(s2%2); s2/=2; } for(i = 0; i<m-s; i++) { Q.push(s1%2); s1/=2; } while(!Q.empty()) { printf("%d",Q.top()); Q.pop(); } printf("\n"); } else printf("%d solutions\n",ans); } return 0;}
0 0
- BAPC2014 K&&HUNNU11591:Key to Knowledge(中途相遇法)
- BAPC2014 K题 Key to Knowledge(中途相遇法,hash,状态压缩)
- 【中途相遇法】【STL】BAPC2014 K Key to Knowledge (Codeforces GYM 100526)
- uva10125 (中途相遇法)
- 中途相遇法
- poj3977 Subset 中途相遇法...
- UvaLive 2965 中途相遇法
- HDU5936 Difference 【中途相遇法】
- poj 1903 中途相遇法
- (中途相遇法)Uva 1618 Weak Key(分段DP+枚举)
- Jurassic Remains,NEERC 2003,中途相遇法
- uva 1326 Jurassic Remains(中途相遇法)
- Uva 1326 - Jurassic Remains 中途相遇法
- LA 2965 - Jurassic Remains 中途相遇法
- LA 2965 Jurassic Remains / 中途相遇法
- uva1326 - Jurassic Remains 中途相遇法
- UVa 10125 - Sumsets (中途相遇法 hash)
- 【UVALive】2965 Jurassic Remains 中途相遇法
- ZOJ 1610 Count the Colors 线段树/暴力模拟
- ubuntu系统 ln 命令使用说明,创建链接
- uva 11524 Values whose Sum is 0
- 并查集 杭电1232畅通工程
- 剑指offer面试题java版系列 题1 Singleton模式
- BAPC2014 K&&HUNNU11591:Key to Knowledge(中途相遇法)
- mysql中使用case when 做where条件筛选表记录
- Java集合类: Set、List、Map、Queue使用场景梳理
- Oil Deposits(dfs深搜)
- ZOJ 2526 FatMouse and JavaBean II 单源最短路 dijkstra
- 实现OPENCV之findcontours函数(一)
- Leetcode Q88:Merge Sorted Array
- PHP 面向对象:抽象类继承抽象类
- hdu 5378 Leader in Tree Land