首页 > 其他分享 >「PKUSC2022」雀圣 题解

「PKUSC2022」雀圣 题解

时间:2024-03-14 17:47:42浏览次数:23  
标签:PKUSC2022 int 题解 sum ++ need now type

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

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

相关文章

  • P1829 / SP8099 Crash的数字表格 题解
    P1829/SP8099Crash的数字表格题解莫比乌斯反演、数论分块、杜教筛。题目传送门题意简述求以下式子的值,对\(20101009\)(一个质数)取模:\[\sum\limits_{i=1}^n\sum\limits_{j=1}^m\operatorname{lcm}(i,j)\]\(n,m\le10^7\)。加强:\(n,m\le10^{10}\)。解法莫比乌斯反......
  • 2024-03 STEMA 考试C++ 中级真题解析
    2024-03-10STEMA考试C++中级真题解析一、选择题(50分)1、    (110010)2+(c3)16的结果是(B )。A.(240)10        B.(11110101)2        C.(366)8        D.(f6)16备注:此题目下标代表进制,因不支持md格式。  2、   表达式1000/3的结果是(......
  • 服务平滑迁移:eureka迁移到nacos。无法注册双中心的问题解决
    迁移的文档:https://www.alibabacloud.com/help/zh/edas/developer-reference/smoothly-migrate-a-spring-cloud-cluster-that-contains-multiple-applications-to-edas其中遇到的问题未配置排除配置项时(exclude={RibbonEurekaAutoConfiguration.class}),ribbonServerList不是......
  • Codeforces Round 933 (Div. 3) A - G 题解
    CodeforcesRound933(Div.3)A-RudolfandtheTicketSolution因为\(n\)很小,直接枚举\(b_i+c_j\)所产生的所有数字Code#include<bits/stdc++.h>usingnamespacestd;voidsolve(){intn,m,k;cin>>n>>m>>k;intans=0;......
  • thinkphp 5 跨域问题解决
    版本:5.1.41LTS从网上搜到好多从/public/index.php添加heade信息,或者用中间件,或者添加behavior操作,可以做到解决跨域问题,但是亲身试验了都不行,今天刚找了一个,可以使用,放在这里header('Access-Control-Allow-Credentials:true');header('Access-Control-Allow-Methods:GET,......
  • 常见问题解决 --- vmware地址分配失败
    vmware是根据分配给客户机的ip决定它处于什么网路。这句话非常抽象,我举例说明,vmware默认有三张网卡,一个桥接网卡,一个nat网卡,一个仅主机。我先说第一中情况 如果里配置客户机是桥接网卡,且在配置器中选择自动桥接。如果里宿主机有一张网卡,那么就桥接那一张网卡。并获取网路内的d......
  • Edu 12 --- Simple Subset -- 题解 (一个比较巧妙的思维算法题)
    SimpleSubset:题解:  思路解析:    题目要求任意两个数的和为质数,那我们最坏情况就是任意选择一个数,此时子集为最大。    如果子集中有两个奇数或者偶数,他们两个之和一定会被2整除,那么我们只能选择一奇一偶。    如果多个奇数都为1的话,他们两两......
  • 【NOIP2013模拟联考8】匹配(match) 题解
    B组都说看不懂……我也解释不清啊……只能写这么详细了ac自动机ac自动机上dp怎么才能判定一个母串是否包含几个模式串?我们可以想到ac自动机,考虑对模式串建ac自动机,如果我们跑到了一个标记为tail的节点,说明我们的母串包含了这一个模式串。所以我们设\(f[i][s][......
  • LeetCode[题解] 2864. 最大二进制奇数
    题目给你一个二进制字符串s,其中至少包含一个'1'。你必须按某种方式重新排列字符串中的位,使得到的二进制数字是可以由该组合生成的最大二进制奇数。以字符串形式,表示并返回可以由给定组合生成的最大二进制奇数。注意返回的结果字符串可以含前导零。示例1:输入:s......
  • 2024.03.13 题解
    CF566A.MatchingNames注意到要求公共前缀,所以先对所有字符串建出Trie树,则公共前缀长度等价于Trie树上两节点最近公共祖先的深度。设\(dfn_u\)表示u点的dfs序,\(dep_u\)表示u的深度,\(lca_{u,v}\)表示\(u\)和\(v\)的最近公共祖先。则对于\(dfn_a<dfn_b<d......