"蔚来杯"2022牛客暑期多校训练营8 题解

D. Poker Game: Decision

对抗搜索+模拟比较两副牌的大小,具体看代码。

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define pii pair<int, int>
#define fi first
#define se second
using namespace std;

const int INF = 10;
const int MAXN = 1e6 + 5;

struct Node {
	pii p[10]; int num = 0;
	
	pii init(string s) {
		pii cur;
		if(s[0] == 'T') s[0] = '0' + 10;
		else if(s[0] == 'J') s[0] = '0' + 11;
		else if(s[0] == 'Q') s[0] = '0' + 12;
		else if(s[0] == 'K') s[0] = '0' + 13;
		else if(s[0] == 'A') s[0] = '0' + 14;
		cur = {s[0] - '0', s[1]};
		return cur;
	}
	
	void push_back(string s) { p[++num] = init(s); }
	void pop_back() { --num; }
}A, B, AA, BB, NUL;

string ss[10];
int st[10], Anum[20], Bnum[20];
pii q[20], num[20];

int Level(Node x) {
	int lvl = 1; x.num = 5;
	sort(x.p + 1, x.p + x.num + 1);
	bool flag, flag1, flag2;

	flag1 = 0, flag2 = 1;
	if(x.p[1].fi + 1 == x.p[2].fi && x.p[2].fi + 1 == x.p[3].fi && x.p[3].fi + 1 == x.p[4].fi && x.p[4].fi + 1 == x.p[5].fi ) flag1 = 1;
	if(x.p[1].fi == 2 && x.p[2].fi == 3 && x.p[3].fi == 4 && x.p[4].fi == 5 && x.p[5].fi == 14 ) flag1 = 1;
	for(int i = 2; i <= x.num; i++) if(x.p[i].se != x.p[i - 1].se) flag2 = 0;
	if(flag1 && flag2) lvl = 9;
	if(lvl == 9 && x.p[5].fi == 14 ) lvl = 10;
	if(lvl >= 9) return lvl;

	flag = 0;
	if(x.p[1].fi == x.p[2].fi && x.p[2].fi == x.p[3].fi && x.p[3].fi == x.p[4].fi) flag = 1;
	if(x.p[2].fi == x.p[3].fi && x.p[3].fi == x.p[4].fi && x.p[4].fi == x.p[5].fi) flag = 1;
	if(flag) return 8;

	flag = 0;
	if(x.p[1].fi == x.p[2].fi && x.p[2].fi == x.p[3].fi && x.p[4].fi == x.p[5].fi) flag = 1;
	if(x.p[1].fi == x.p[2].fi && x.p[3].fi == x.p[4].fi && x.p[4].fi == x.p[5].fi) flag = 1;
	if(flag) return 7;

	flag = 1;
	for(int i = 2; i <= x.num; i++) if(x.p[i].se != x.p[i - 1].se) flag = 0;
	if(flag) return 6;
	
	flag = 0;
	if(x.p[1].fi + 1 == x.p[2].fi && x.p[2].fi + 1 == x.p[3].fi && x.p[3].fi + 1 == x.p[4].fi && x.p[4].fi + 1 == x.p[5].fi ) flag = 1;
	if(x.p[1].fi == 2 && x.p[2].fi == 3 && x.p[3].fi == 4 && x.p[4].fi == 5 && x.p[5].fi == 14 ) flag = 1;
	if(flag) return 5;	

	flag = 0;
	for(int i = 3; i <= x.num; i++) if(x.p[i].fi == x.p[i - 1].fi && x.p[i].fi == x.p[i - 2].fi) flag = 1;
	if(flag) return 4;
	
	flag = 0;
	for(int i = 2; i <= x.num; i++) for(int j = i + 2; j <= x.num; j++) if(x.p[i].fi == x.p[i - 1].fi && x.p[j].fi == x.p[j - 1].fi) flag = 1;
	if(flag) return 3;	
	
	flag = 0;
	for(int i = 2; i <= x.num; i++) if(x.p[i].fi == x.p[i - 1].fi) flag = 1;
	if(flag) return 2;
	
	return 1;
}

void Print(Node x) {
	for(int i = 1; i <= 5; i++) cout << x.p[i].fi << "," << x.p[i].se << " "; cout << " poker\n";
	sort(x.p + 1, x.p + 5 + 1);
	for(int i = 1; i <= 5; i++) cout << x.p[i].fi << "," << x.p[i].se << " "; cout << " sort poker\n";	
	cout << Level(x) << " level\n\n";
}

void Sort(int* cnum, Node x, int cnt = 0) {
	for(int i = 1; i <= 14; i++) num[i] = {0, i};
	for(int i = 1; i <= 5; i++) num[ x.p[i].fi ].fi++;
	sort(num + 1, num + 1 + 14, [&](const pii& a, const pii& b) {
		if(a.fi == b.fi) return a.se > b.se;
		return a.fi > b.fi;
	});
	for(int i = 1; i <= 14; i++) {
		if(num[i].fi == 0) break;
		for(int j = 1; j <= 5; j++) if(x.p[j].fi == num[i].se) q[++cnt] = x.p[j];
	}
	for(int i = 1; i <= 5; i++) cnum[i] = q[i].fi;
	if(cnum[1] == 14 && cnum[2] == 5 && cnum[3] == 4 && cnum[4] == 3 && cnum[5] == 2 ) cnum[1] = 5, cnum[2] = 4, cnum[3] = 3, cnum[4] = 2, cnum[5] = 1;
}

int cal() {
	int lvlA = Level(A), lvlB = Level(B);
	if(lvlA > lvlB) return 1;
	else if(lvlA < lvlB) return -1;
	else {
		Sort(Anum, A); Sort(Bnum, B);
		for(int i = 1; i <= 5; i++) {
			if(Anum[i] < Bnum[i]) return -1;
			if(Anum[i] > Bnum[i]) return 1;
		}
		return 0;
	}
}

int dfs(int pos,int type,int Alpha,int Beta) {
	if(pos == 7) return cal();
	int ans = type?INF:-INF;
	for(int i=1;i<=6;++i){
		if(st[i] == 1) continue;
		st[i] = 1;
		if(pos % 2) A.push_back(ss[i]);
		else B.push_back(ss[i]);
		int tmp = dfs(pos+1,type ^ 1,Alpha,Beta);
		type ? Beta = min(Beta,tmp) : Alpha = max(Alpha,tmp);
		st[i] = 0;
		if(pos % 2) A.pop_back();
		else B.pop_back();
		if(Alpha >= Beta) break;
	}
	return type ? Beta : Alpha;
} 

void Solve() {
	string s1, s2; A.num = 0, B.num = 0;
	cin >> s1 >> s2; A.push_back(s1), A.push_back(s2);
	cin >> s1 >> s2; B.push_back(s1), B.push_back(s2);
	for(int i = 1; i <= 6; i++) cin >> ss[i];
	int cur = dfs(1, 0, -INF, INF);
	if(cur == 1) cout << "Alice";
	else if(cur == 0) cout << "Draw";
	else cout << "Bob";
	cout << "\n";
}

signed main()
{
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	int T; cin >> T;
	while(T--) Solve();
	return 0;
} 

F. Longest Common Subsequence

对于序列 \(t\),发现如果有一个数和 \(s\) 中的某一个数相等,那么根据构造方式,可知接在其后面的所有数都相等,其 lcs 一定是连续的。

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define int long long
using namespace std;

const int INF = 0x3f3f3f3f;
const int MAXN = 1e6 + 5;

int n, m, p, x, a, b, c, len, vals[MAXN], minn[MAXN], A[MAXN];

int Map(int x) {
	int pos = lower_bound(vals + 1, vals + 1 + len, x) - vals;
	if(pos <= 0 || pos > len || vals[pos] != x) return 0;
	return pos;
}

void Solve() {
	cin >> n >> m >> p >> x >> a >> b >> c;
	for(int i = 1; i <= n; i++) {
		x = (a * x % p * x % p + b * x % p + c % p) % p;
		vals[i] = A[i] = x;
		minn[i] = INF;
	}
	sort(vals + 1, vals + 1 + n);
	len = unique(vals + 1, vals + 1 + n) - vals - 1;
	for(int i = n; i >= 1; i--) {
		A[i] = Map(A[i]);
		minn[ A[i] ] = i;
	}
	int ans = 0;
	for(int i = 1; i <= m; i++) {
		x = (a * x % p * x % p + b * x % p + c) % p;
		int cur = Map(x);
		if(cur) ans = max(ans, (int)min(m - i + 1, n - minn[cur] + 1) );
	}
	cout << ans << "\n";
}

signed main()
{
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	int T; cin >> T;
	while(T--) Solve();
	return 0;
} 
posted @ 2022-08-18 09:55  Orzjh  阅读(27)  评论(0)    收藏  举报