「PKUSC2022」雀圣 题解

这边电脑的输入法要把我干烧了。。

D2T3出这种模拟题,那简直不要太好。

首先,不难想到暴力搜索要摸那些牌,然后丢哪些牌。

然后手搓一些 \(\texttt{check}\),这个应该都会,但是实际上比正解难写。

我不知道 \(\texttt{lay}\) 打的什么东西,比我快20多倍,但是个人认为我这个思路挺暴力的。

就是,你发现既然正着来,你虽然可以枚举5张牌,但是你就会在 \(\texttt{check}\) 上浪费很多时间,导致超时。

那我不 \(\texttt{check}\) 不就行了嘛。

我们考虑直接搜索构造出来所有合法的牌型,可以先不关注花色,因为花色我们最后算差异的时候可以排列组合用最小的那个,这一步应该比较简单。(注意,构造出来的是14张,不是13张)

然后,每搜出来一种,你就去算他需要在原牌经过多少次摸和弃而得到。显然,原牌比构造出来的牌所多出来的那一部分,就是你需要弃掉的牌,然后弃掉牌的时候,你又可以摸一张,就可以把差的给摸起来,然后在通过听牌而虚构的那一张牌,你就可以从原牌达到构造的牌。

最后,你把所有的多出来的那一部分取最小值即可。

所以,这个故事告诉了我们,爆搜的时候,只需要稍微动点脑子,你就可以打出正解。

另外,这个题完全可以加强一下,因为这个算法跟他要经过多少步没有任何关系(因为是算差异求最小值。)

代码

#include <bits/stdc++.h>
using namespace std;
string a;
int x[3][10], y[3][10];
void init()
{
	for (int i = 0; i < a.length(); ++i)
	{
		if(a[i] == 'm') for (int j = 0; j < i; ++j) x[0][a[j] - '0']++;
		else if(a[i] == 'p')
		{
			for (int j = i - 1; j; --j)
			{
				if(a[j] == 'm') break;
				x[1][a[j] - '0']++;
			}
		}
		else if(a[i] == 's')
		{
			for (int j = i - 1; j; --j)
			{
				if(a[j] == 'p') break;
				x[2][a[j] - '0']++;
			}
		}
	}
}
int d[6][3];
int ans = 5;
void dfs1(int need, int type, int now)
{
	if(!need)
	{
		int sum = 0;
		for (int i = 0; i < 3; ++i)
		{
			for (int j = 1; j <= 9; ++j)
			if(x[i][j] > y[i][j])
			sum += abs(x[i][j] - y[i][j]);
		}
		ans = min(ans, sum);
		return;
	}
	if(now > 9)
	{
		++type, now = 1;
		if(type > 2) return;
	}
	dfs1(need, type, now + 1);
	y[type][now] += 2;
	dfs1(need - 1, type, now + 1);
	y[type][now] -= 2;
}
void dfs2(int need, int type, int now)
{
	if(!need)
	{
		for (int qwq = 0; qwq < 6; ++qwq)
		{
			int sum = 0;
			for (int i = 0; i < 3; ++i)
			{
				for (int j = 1; j <= 9; ++j)
				if(x[i][j] > y[d[qwq][i]][j])
				sum += abs(x[i][j] - y[d[qwq][i]][j]);
			}
			ans = min(ans, sum);
		}
		return;
	}
	if(now > 9)
	{
		++type, now = 1;
		if(type > 2) return;
	}
	dfs2(need, type, now + 1);
	if(y[type][now] <= 1)
	{
		y[type][now] += 3;
		dfs2(need - 1, type, now + 1);
		y[type][now] -= 3;
	}
	if(y[type][now] < 4 && now < 8 && y[type][now + 1] < 4 && y[type][now + 2] < 4)
	{
		y[type][now]++, y[type][now + 1]++, y[type][now + 2]++;
		dfs2(need - 1, type, now);
		y[type][now]--, y[type][now + 1]--, y[type][now + 2]--;
	}
}
int main()
{
	cin >> a;
	init();
	dfs1(7, 0, 1);
	d[0][0] = 0; d[0][1] = 1; d[0][2] = 2;
	d[1][0] = 0; d[1][1] = 2; d[1][2] = 1;
	d[2][0] = 1; d[2][1] = 0; d[2][2] = 2;
	d[3][0] = 1; d[3][1] = 2; d[3][2] = 0;
	d[4][0] = 2; d[4][1] = 0; d[4][2] = 1;
	d[5][0] = 2; d[5][1] = 1; d[5][2] = 0;
	for (int i = 1; i <= 9; ++i) y[0][i] += 2, dfs2(4, 0, 1), y[0][i] -= 2;
	cout << ans << endl;
	return 0;
}
posted @ 2024-03-14 17:31  Saltyfish6  阅读(9)  评论(0编辑  收藏  举报
Document