您的位置:首页 > 其它

[CF442A] Borya and Hanabi (暴力bitmask)

2015-05-31 00:23 183 查看
题目链接:http://codeforces.com/problemset/problem/442/A

题目大意:给你n张卡片,你知道这n张卡片都是什么,但是不知道他们的位置。你每次可以请求朋友指出一种颜色的卡片,或者一种数字的卡片。问你最少需要多少次能够知道每个卡片的位置。

首先,如果其他所有卡片都知道了,最后一张卡片不需要指示就知道了。

然后我们枚举哪张是最后一张卡片。

将五种颜色放在x轴,5个数字放在y轴。

一次询问就是画一条线,先去掉交叉点,再看剩下的点是不是唯一在一条直线里。

bitmask,一共最多25条线。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <bitset>
#include <cmath>
#include <numeric>
#include <iterator>
#include <iostream>
#include <cstdlib>
#include <functional>
#include <queue>
#include <stack>
#include <string>
#include <cctype>
using namespace std;
#define PB push_back
#define MP make_pair
#define SZ size()
#define ST begin()
#define ED end()
#define CLR clear()
#define ZERO(x) memset((x),0,sizeof(x))
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
const double EPS = 1e-8;

struct POINT{
int x,y;
int hash,idx;
};

int n,tot;
vector<POINT> pts;
set<int> se;
vector<POINT> vx[10],vy[10];

POINT GetPoint(const char* buf){
POINT res;
if( buf[0] == 'R' ) res.x = 1;
else if( buf[0] =='G' ) res.x = 2;
else if( buf[0] == 'B' ) res.x = 3;
else if( buf[0] == 'Y' ) res.x = 4;
else if( buf[0] == 'W' ) res.x = 5;
res.y = buf[1] -'0';
res.hash = res.x*10+res.y;
return res;
}

void SplitPoints() {
for(int i=0;i<pts.size();i++){
POINT &pt = pts[i];
vx[pt.x].PB(pt);
vy[pt.y].PB(pt);

//        printf("vx[%d].PB(%d)\n",pt.x,pt.idx);
//        printf("vy[%d].PB(%d)\n",pt.y,pt.idx);
}
}

bool check(int mask,int out) {

int vis[33];
for(int i=0;i<33;i++) vis[i] = 0;

for( int i=0;i<10;i++ ){
if( (mask>>i)&1 ) {
int now = i+1;
if(now<=5) {
if( vx[now].size()==0 ) return false;
} else {
now -= 5;
if( vy[now].size()==0 ) return false;
}
}
}

//    if(mask==261) puts("****");

for( int i=0;i<10;i++ ) {
if( (mask>>i)&1 ) {
int now = i+1;
//            if(mask==261) printf("now i=%d\n",now);
if( now<=5 ) {
for(int j=0;j<vx[now].size();j++){
if( vis[vx[now][j].idx] == 2 ) continue;
vis[vx[now][j].idx]++;
}
} else {
now -= 5;
for(int j=0;j<vy[now].size();j++){
if( vis[vy[now][j].idx]==2 ) continue;
vis[vy[now][j].idx]++;
}
}
}
}

for(int i=0;i<10;i++){
if( (mask>>i)&1 ) {
int now = i+1;
if( now<=5 ) {
// x
int cnt = 0;
for(int j=0;j<vx[now].size();j++) if(vis[vx[now][j].idx]<2) cnt++;
if( cnt==1 ) {
for(int j=0;j<vx[now].size();j++) if( vis[vx[now][j].idx] < 2)
{
vis[vx[now][j].idx] = 2; break;
}
}
} else {
// y
now -= 5;
int cnt = 0;
for(int j=0;j<vy[now].size();j++) if(vis[vy[now][j].idx]<2) cnt++;
if( cnt==1 ) {
for(int j=0;j<vy[now].size();j++) if(vis[vy[now][j].idx]<2){
vis[vy[now][j].idx] = 2;
break;
}
}
}
}
}

bool res = true;
for(int i=0;i<tot;i++){
//        printf("vis[%d]=%d\n",i,vis[i]);
if(vis[i]<2&&i!=out) {
res = false;
break;
}
}

return res;
}

int main() {
tot = 0;
scanf("%d",&n);
for(int i=0;i<n;i++){
char buf[11];
scanf("%s",buf);
POINT pt = GetPoint(buf);
if( se.find(pt.hash) == se.end() ){
se.insert(pt.hash);
pt.idx = tot++;
pts.PB(pt);
}
}

//    for(int i=0;i<pts.size();i++){
//        printf("%d,%d\n",pts[i].x,pts[i].y);
//    }
//    printf("size = %d\n",pts.size());

SplitPoints();
int ans = 2*tot;
for(int i=0;i<(1<<10);i++) {
for(int j=0;j<tot;j++){
if( check(i,j) ) {
//if(__builtin_popcount(i)==10&&fff==-1) printf("i=%d , ans = %d\n",i,__builtin_popcount(i));
ans = min( ans,__builtin_popcount(i) );
}
}
}
//    printf("tot = %d\n", tot);
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: