首页 > 其他分享 >ABC361-D题解

ABC361-D题解

时间:2024-07-17 17:12:01浏览次数:11  
标签:字符 ch int 题解 空格 字符串 ABC361 include

背景

保佑LC能来一中。

题意

给你一个长度为 \(n\) 的初始字符串和目标字符串,都由 WB 两种字符构成。

现在初始字符串末尾接有两个空格字符,每次你可以在该字符串中选出连续两个非空格字符,并把它们按顺序与两个空格交换位置。问最少需要几步能得到目标字符串。

分析

首先如果两字符串中 WB 字符的数量不相等,那么一定无解。

由于 \(n\leq 14\),那么算法应该是搜索。因为要求最小步数,所以考虑 BFS 算法。

然后每次选出队头,枚举所有非空格字符,与空格字符交换后扔进队列,再写一个记忆化就能过了。

Code

#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/hash_policy.hpp>
#include<ext/pb_ds/trie_policy.hpp>
#include<ext/pb_ds/priority_queue.hpp>
#define int long long
using namespace std;
using namespace  __gnu_pbds;
//gp_hash_table<string,int>mp2;
//__gnu_pbds::priority_queue<int,less<int>,pairing_heap_tag> q;
inline int read()
{
	int w=1,s=0;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
	while(isdigit(ch)){s=s*10+(ch-'0');ch=getchar();}
	return w*s;
}
const int mod=998244353;
const int maxn=1e6+10;
int n;
string s,t;
int sw,sb,tw,tb;
struct no
{
	string ss;
	int ans;
};
map<string,bool> mp;
signed main()
{
//	freopen("xxx.in","r",stdin);
//	freopen("xxx.out","w",stdout);
	cin>>n>>s>>t;
	for(int i=1;i<=2;i++)s=s+'.';
	for(int i=1;i<=2;i++)t=t+'.';
	for(int i=0;i<s.size();i++)
	{
		if(s[i]=='W')sw++;
		else sb++;
	}
	for(int i=0;i<t.size();i++)
	{
		if(t[i]=='W')tw++;
		else tb++;
	}
	if(sw!=tw||sb!=tb)return 0*printf("-1");
	queue<no>q;
	q.push({s,0});
	mp[s]=1;
	while(!q.empty())
	{
		string ss=q.front().ss;
		int ans=q.front().ans;
		q.pop();
		if(ss==t)
		{
			cout<<ans;
			return 0;
		}
		int tt=0;
		for(int i=0;i<ss.size()-1;i++)
		{
			if(ss[i]=='.'&&ss[i+1]=='.')
			{
				tt=i;
				break;
			}
		}
		for(int i=0;i<ss.size()-1;i++)
		{
			if(ss[i]!='.'&&ss[i+1]!='.')
			{
				swap(ss[i],ss[tt]);
				swap(ss[i+1],ss[tt+1]);
				if(!mp[ss]){mp[ss]=1;q.push({ss,ans+1});}
				swap(ss[i],ss[tt]);
				swap(ss[i+1],ss[tt+1]);
			}
		}
	}
	cout<<-1;
	return 0;
}

标签:字符,ch,int,题解,空格,字符串,ABC361,include
From: https://www.cnblogs.com/fengyixuan2027/p/18307829

相关文章

  • ABC361-C题解
    背景昨天打比赛的时候查了中考分,心快停跳了。题意从\(n\)个数字中删除\(k\)个数字,问剩下的数字中极差的最小值。分析首先把这\(n\)个数字排序,然后问题就可以转化为求这\(n\)个数字中所有长度为\(n-k\)的连续子段的极差的最小值。采用尺取法,可以从\(1\)开始枚举......
  • 题解:AT_abc360_c [ABC360C] Move It
    背景机房大佬掉大分了,乐悲。题意给你几个箱子和每个箱子里装有的东西\(a\)和对应的重量\(w\),现在要让每个箱子里都装有一个东西,每次可以移动任意一个箱子中的任意一个东西,代价为它的重量,问最小代价。分析贪心。首先最终状态里所有箱子一定只有一个东西,那么对于所有装东西......
  • 题解:P10723 [GESP202406 七级] 黑白翻转
    背景汗流浃背了。分析容易想到一个显然的思路:以任意节点为根,开始遍历。如果一个节点的子树里面有黑点,那么它必须保留,否则如果它是白点,则可以删去。但这个方法很容易举出反例:在这颗树中,如果以最上面的白点为根,那么手推发现算法显然错误。尝试进行修改,容易发现,对于类似的情况......
  • 题解:P10722 [GESP202406 六级] 二叉树
    题意一颗\(n\)节点的二叉树,每个节点非黑即白,给你\(Q\)次操作,每次给你一个\(u\),把\(u\)的子树内所有节点颜色反转,问最终每个节点的颜色。分析看到数据范围,首先把操作离线。容易发现如果一个节点重复操作奇数次,等效于操作一次,如果重复操作偶数次,等效于没操作。所以我们可......
  • 题解:B3646 数列前缀和 3
    分析板子题,线段树维护矩阵区间积,除了难写没什么思维难度。所以直接放代码吧。Code#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;inlineintread(){ intx=0,f=1;charch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getcha......
  • Masked Popcount 题解
    背景罚了一发,太菜了。为什么我终于有时间的时候她要考试?题意给你\(n,m\),问\(\sum_{i=0}^{n}popcount(i\&m)\)。其中\(\&\)代表位运算,\(popcount\)代表一个数字二进制下\(1\)的个数。分析两个数字在二进制下根据数据范围有\(60\)位。所以我们考虑每一位对答案的贡......
  • 题解:AT_abc359_c [ABC359C] Tile Distance 2
    背景去中考了,比赛没打,来补一下题。分析这道题让我想起了这道题(连题目名称都是连着的),不过显然要简单一些。这道题显然要推一些式子。我们发现,和上面提到的那道题目一样,沿着对角线走台阶,纵坐标走到以后再走横坐标显然是最优策略。这时候的答案就是横纵坐标差的和的一半(这就不用......
  • 题解:AT_abc357_f [ABC357F] Two Sequence Queries
    题意维护一个数据结构,支持两个数列的区间求和,和查询区间内两数列各元素积的和。分析线段树万岁!这道题要维护两个序列,所以线段树中要同时存储两个区间和。但还要在维护一个信息,是该区间内两序列元素积的和。大概长这样:structno{ intl,r; intda,db,ab; intta,tb;}t[m......
  • ABC357-C题解
    最近一直掉分,谔谔。分析发现机房里面除了我以外都用递归写的,那我就来讲一种非递归的吧。考虑第\(i\)级地毯拆成九块以后其实就是八块第\(i-1\)级地毯与一块大小为\(3^{i-1}\times3^{i-1}\)大小的白色地毯。所以用一个三维数组记录每一级地毯的状态,然后循环往上跑,每一级......
  • 题解:P10417 [蓝桥杯 2023 国 A] 第 K 小的和
    分析这道题不是板子么。先对序列排序,然后二分答案,设当前答案为\(x\),枚举\(a\)中的数,然后二分查找\(b\)中不大于\(x-a\)的元素个数,累加判断是否不大于\(k\)。然后稍微调一调端点就过了。Code#include<bits/stdc++.h>#include<ext/pb_ds/assoc_container.hpp>#incl......