1. 程式人生 > 實用技巧 >20/08/01測試

20/08/01測試

T1

這道題可以用雙端搜尋寫,但因為蒟蒻少判了情況丟了20分。其實考試時想到了但懶得改qaq

#include <bits/stdc++.h>
using namespace std;

const int maxn = 20;

int n, m, vis[2][1<<12], dis[2][1<<12];

struct node{
	int val[maxn];
}e[200];

void bfs(){
	queue<int> q_start, q_end;
	int qwq[11], qaq = 0;
	for(int i = 1; i <= n; i ++) qwq[i] = 1;
	for(int i = 1; i <= n; i ++) if(qwq[n-i+1]) qaq += 1<<(i-1);
	q_start.push(qaq), q_end.push(0);
	vis[0][qaq] = 1, vis[1][0] = 1; 
	while(q_start.size() or q_end.size()){
		if(1 or 1 or 1 or 1){
			int now = q_start.front();
			q_start.pop();
			int cnt = 0, cmp = now, a[11], tmp[11];
			memset(tmp, 0, sizeof(tmp));
			while(cmp){
				tmp[++cnt] = cmp&1;
				cmp >>= 1;
			}
			for(int i = 1; i <= n; i ++) a[i] = tmp[n-i+1];
			int b[11];
			for(int i = 1; i <= m; i ++){
				for(int j = 1; j <= n; j ++){
					if(e[i].val[j] ==-1) b[j] = 1;
					if(e[i].val[j] == 1) b[j] = 0;
					if(e[i].val[j] == 0) b[j] = a[j];
				}
				int turned = 0;
				for(int i = 1; i <= n; i ++) if(b[n-i+1]) turned += 1<<(i-1);
				if(!vis[0][turned]){
					q_start.push(turned);
					vis[0][turned] = 1;
					dis[0][turned] = dis[0][now] + 1;
				}
				if(vis[1][turned]){
					printf("%d\n", dis[0][turned]+dis[1][turned]);
					return;
				}
			}
		}
		if(1 or 1 or 1 or 1){
			int now = q_end.front();
			q_end.pop();
			int cnt = 0, cmp = now, a[11], tmp[11];
			memset(tmp, 0, sizeof(tmp));
			while(cmp){
				tmp[++cnt] = cmp&1;
				cmp >>= 1;
			}
			for(int i = 1; i <= n; i ++) a[i] = tmp[n-i+1];
			int b[11];
			for(int i = 1; i <= m; i ++){
				for(int j = 1; j <= n; j ++){
					if((e[i].val[j] ==-1 and !b[j])or(e[i].val[j] == 1 and b[j])) continue;
					if(e[i].val[j] ==-1) b[j] = 0;
					if(e[i].val[j] == 1) b[j] = 1;
					if(e[i].val[j] == 0) b[j] = a[j];
				}
				int turned = 0;
				for(int i = 1; i <= n; i ++) if(b[n-i+1]) turned += 1<<(i-1);
				if(!vis[1][turned]){
					q_end.push(turned);
					vis[1][turned] = 1;
					dis[1][turned] = dis[1][now] + 1;
				}
				if(vis[0][turned]){
					printf("%d\n", dis[0][turned]+dis[1][turned]);
					return;
				}
			}
		}
	}
	printf("-1\n");
	return;
}

signed main(){
	freopen("flame.in", "r", stdin);
	freopen("flame.out", "w", stdout);
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; i ++){
		for(int j = 1; j <= n; j ++){
			scanf("%d", &e[i].val[j]); 
		}
	}
	bfs();
	return 0;
}