标签:
题目链接:http://codeforces.com/problemset/problem/442/A
题目大意:给你n张卡片,你知道这n张卡片都是什么,但是不知道他们的位置。你每次可以请求朋友指出一种颜色的卡片,或者一种数字的卡片。问你最少需要多少次能够知道每个卡片的位置。
首先,如果其他所有卡片都知道了,最后一张卡片不需要指示就知道了。
然后我们枚举哪张是最后一张卡片。
将五种颜色放在x轴,5个数字放在y轴。
一次询问就是画一条线,先去掉交叉点,再看剩下的点是不是唯一在一条直线里。
bitmask,一共最多25条线。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <vector> 5 #include <map> 6 #include <set> 7 #include <bitset> 8 #include <cmath> 9 #include <numeric> 10 #include <iterator> 11 #include <iostream> 12 #include <cstdlib> 13 #include <functional> 14 #include <queue> 15 #include <stack> 16 #include <string> 17 #include <cctype> 18 using namespace std; 19 #define PB push_back 20 #define MP make_pair 21 #define SZ size() 22 #define ST begin() 23 #define ED end() 24 #define CLR clear() 25 #define ZERO(x) memset((x),0,sizeof(x)) 26 typedef long long LL; 27 typedef unsigned long long ULL; 28 typedef pair<int,int> PII; 29 const double EPS = 1e-8; 30 31 struct POINT{ 32 int x,y; 33 int hash,idx; 34 }; 35 36 int n,tot; 37 vector<POINT> pts; 38 set<int> se; 39 vector<POINT> vx[10],vy[10]; 40 41 POINT GetPoint(const char* buf){ 42 POINT res; 43 if( buf[0] == ‘R‘ ) res.x = 1; 44 else if( buf[0] ==‘G‘ ) res.x = 2; 45 else if( buf[0] == ‘B‘ ) res.x = 3; 46 else if( buf[0] == ‘Y‘ ) res.x = 4; 47 else if( buf[0] == ‘W‘ ) res.x = 5; 48 res.y = buf[1] -‘0‘; 49 res.hash = res.x*10+res.y; 50 return res; 51 } 52 53 void SplitPoints() { 54 for(int i=0;i<pts.size();i++){ 55 POINT &pt = pts[i]; 56 vx[pt.x].PB(pt); 57 vy[pt.y].PB(pt); 58 59 // printf("vx[%d].PB(%d)\n",pt.x,pt.idx); 60 // printf("vy[%d].PB(%d)\n",pt.y,pt.idx); 61 } 62 } 63 64 bool check(int mask,int out) { 65 66 int vis[33]; 67 for(int i=0;i<33;i++) vis[i] = 0; 68 69 for( int i=0;i<10;i++ ){ 70 if( (mask>>i)&1 ) { 71 int now = i+1; 72 if(now<=5) { 73 if( vx[now].size()==0 ) return false; 74 } else { 75 now -= 5; 76 if( vy[now].size()==0 ) return false; 77 } 78 } 79 } 80 81 // if(mask==261) puts("****"); 82 83 for( int i=0;i<10;i++ ) { 84 if( (mask>>i)&1 ) { 85 int now = i+1; 86 // if(mask==261) printf("now i=%d\n",now); 87 if( now<=5 ) { 88 for(int j=0;j<vx[now].size();j++){ 89 if( vis[vx[now][j].idx] == 2 ) continue; 90 vis[vx[now][j].idx]++; 91 } 92 } else { 93 now -= 5; 94 for(int j=0;j<vy[now].size();j++){ 95 if( vis[vy[now][j].idx]==2 ) continue; 96 vis[vy[now][j].idx]++; 97 } 98 } 99 } 100 } 101 102 for(int i=0;i<10;i++){ 103 if( (mask>>i)&1 ) { 104 int now = i+1; 105 if( now<=5 ) { 106 // x 107 int cnt = 0; 108 for(int j=0;j<vx[now].size();j++) if(vis[vx[now][j].idx]<2) cnt++; 109 if( cnt==1 ) { 110 for(int j=0;j<vx[now].size();j++) if( vis[vx[now][j].idx] < 2) 111 { 112 vis[vx[now][j].idx] = 2; break; 113 } 114 } 115 } else { 116 // y 117 now -= 5; 118 int cnt = 0; 119 for(int j=0;j<vy[now].size();j++) if(vis[vy[now][j].idx]<2) cnt++; 120 if( cnt==1 ) { 121 for(int j=0;j<vy[now].size();j++) if(vis[vy[now][j].idx]<2){ 122 vis[vy[now][j].idx] = 2; 123 break; 124 } 125 } 126 } 127 } 128 } 129 130 bool res = true; 131 for(int i=0;i<tot;i++){ 132 // printf("vis[%d]=%d\n",i,vis[i]); 133 if(vis[i]<2&&i!=out) { 134 res = false; 135 break; 136 } 137 } 138 139 return res; 140 } 141 142 143 144 int main() { 145 tot = 0; 146 scanf("%d",&n); 147 for(int i=0;i<n;i++){ 148 char buf[11]; 149 scanf("%s",buf); 150 POINT pt = GetPoint(buf); 151 if( se.find(pt.hash) == se.end() ){ 152 se.insert(pt.hash); 153 pt.idx = tot++; 154 pts.PB(pt); 155 } 156 } 157 158 // for(int i=0;i<pts.size();i++){ 159 // printf("%d,%d\n",pts[i].x,pts[i].y); 160 // } 161 // printf("size = %d\n",pts.size()); 162 163 SplitPoints(); 164 int ans = 2*tot; 165 for(int i=0;i<(1<<10);i++) { 166 for(int j=0;j<tot;j++){ 167 if( check(i,j) ) { 168 //if(__builtin_popcount(i)==10&&fff==-1) printf("i=%d , ans = %d\n",i,__builtin_popcount(i)); 169 ans = min( ans,__builtin_popcount(i) ); 170 } 171 } 172 } 173 // printf("tot = %d\n", tot); 174 printf("%d\n",ans); 175 return 0; 176 }
[CF442A] Borya and Hanabi (暴力bitmask)
标签:
原文地址:http://www.cnblogs.com/llkpersonal/p/4541344.html