Luogu P4907 A换B problem

题目传送门

暴力乱搞大法好!

感觉这题难度有点虚,最多蓝题吧


一开始写了个没有一丝剪枝的搜索交了上去,水到了\(60pts\)
于是加了个卡时,就\(A\)

顺便说一句,数据略水(可能也是因为乱搞不好卡吧)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <ctime>
#define LL long long
using namespace std;
LL read() {
	LL k = 0, f = 1; char c = getchar();
	while(c < '0' || c > '9') {
		if(c == '-') f = -1;
		c = getchar();
	}
	while(c >= '0' && c <= '9')
		k = k * 10 + c - 48, c = getchar();
	return k * f;
}
bool tong[5][100]; //tong[花色][点数]
struct zzz {
	int c, k;
}a[100]; //c:花色,k:点数
bool flag;
int n, ans = 100, ans2 = 100, kti;
bool judge() { //判断是否为顺子
	int num = 0; bool flag2 = 1;
	for(int i = 1; i <= 4; ++i) {
		int minn = 100, maxn = 0;
		for(int j = 1; j <= 13; ++j) {
			if(tong[i][j] && minn == 100) minn = j;
			if(tong[i][j]) maxn = max(maxn, j);
		}
		for(int j = minn; j <= maxn; ++j)
			if(!tong[i][j]) flag2 = 0, ++num;
	}
	ans2 = min(ans2, num);
	return flag2;
}
void dfs(int pos, int tot) {
	if(tot >= ans) return ;
	if(judge()) {
		ans = min(ans, tot);
		return ;
	}
	if(pos > n) return ;
	//=====卡时
	if((clock() - kti) * 1000 >= 980 * CLOCKS_PER_SEC){
    	if(ans <= 52) printf("Yes\n%d", ans);
		else printf("No\n%d", ans2);
		exit(0);
    }
    //=====
	for(int i = 1; i <= 4; ++i) {
		if(tong[i][a[pos].k] && i != a[pos].c) continue;
		tong[a[pos].c][a[pos].k] = 0;
		tong[i][a[pos].k] = 1;
		if(i != a[pos].c) dfs(pos+1, tot+1);
		else dfs(pos+1, tot);
		tong[i][a[pos].k] = 0, tong[a[pos].c][a[pos].k] = 1;
	}
}
int main() {
	kti = clock(), n = read();
	for(int i = 1; i <= n; ++i) {
		a[i].c = read();
		char c[2]; cin >> c;
		if(c[0] == 'A') a[i].k = 1;
		else if(c[0] == 'J') a[i].k = 11;
		else if(c[0] == 'Q') a[i].k = 12;
		else if(c[0] == 'K') a[i].k = 13;
		else if(c[0] == '1') a[i].k = 10;
		else a[i].k = c[0] - '0';
	}
	for(int i = 1; i <= n; ++i) tong[a[i].c][a[i].k] = 1;
	dfs(1, 0);
	if(ans <= 52) printf("Yes\n%d", ans);
	else printf("No\n%d", ans2);
	return 0;
}
posted @ 2019-11-14 11:08  MorsLin  阅读(186)  评论(0编辑  收藏  举报