这边电脑的输入法要把我干烧了。。
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;
}
标签:PKUSC2022,int,题解,sum,++,need,now,type
From: https://www.cnblogs.com/SFsaltyfish/p/18073541