首页 > 其他分享 >CF1785B Letter Exchange 题解(思维+模拟)

CF1785B Letter Exchange 题解(思维+模拟)

时间:2023-02-07 21:12:23浏览次数:89  
标签:return Exchange int 题解 text vec Letter res define

题目链接

难度:绿+。

题意

给定 \(t\) 组 testcase,每组 testcase 如下。

有 \(m\) 个长度为 3 的字符串,每个字符都是 \(\text{w}\)、\(\text{i}\)、\(\text{n}\) 中的一个,一共有 \(m\) 个 \(\text{w}\),\(m\) 个 \(\text{i}\) 和 \(m\) 个 \(\text{n}\)。

现在要求用最少次数的交换使得每个字符串都变成 \(\text{w}\)、\(\text{i}\)、\(\text{n}\) 各有一个,并输出方案。

题解

题目本身不难,但是很有趣,感觉分数有点打低了,不过听说 CF 普遍把思维打得比较低。

最让人头疼的问题是要交换次数最小,怎么样才能保证最小?或者说什么样的取法是最优方案?

观察到有 wwniin 这种只要交换一次就能让两个都结束,肯定优先交换这种的。

将 \(\text{w}\) 设为 0,\(\text{i}\) 设为 1,\(\text{n}\) 设为 2,则所有字符串都可以用 012 来表示。例如 wwn002iin112 等。

分析什么样的可以一下就两个都消掉,发现是一个 \(x\) 多 \(y\) 少,另一个 \(y\) 多 \(x\) 少的情况。例如 002 就是 0 多 1 少,112 就是 1 多 0 少,所以这两个可以直接消掉。

特殊地,000 这种三个都是一样的就既算 0 多 1 少,也算 0 多 2 少,容易证明这样也是对的。

除了能直接消掉的就是三个一组的消了。为了书写方便,记 \(x\) 多 \(y\) 少的字符串用二元组 \((x,y)\) 表示。则三个一组只有两种情况:\((0,1),(1,2),(2,0)\) 和 \((1,0),(0,2),(2,1)\)。

实现

这道题的实现每个人写出来都不一样,我觉得我写得比较简单。

把 \((x,y)\) 的字符串存到一个 vector<int> vec[3][3] 中的 vec[x][y] 里。

#include<bits/stdc++.h>
#define int long long
#define rep(i,n) for(int i=0;i<n;i++)
#define rept(i,n) for(int i=1;i<=n;i++)
#define repe(i,l,r) for(int i=l;i<=r;i++)
#define FOR(i,r,l) for(int i=r;i>=l;i--)
#define fi first
#define se second
#define pii pair<int,int>
#define mpr make_pair
#define pb push_back
#define sz(v) (int)(v.size())
using namespace std;
int fast(int a,int b,int P){int res=1;if(P<=0){while(b){if(b&1)res=res*a;a=a*a;b>>=1;}}else{while(b){if(b&1)res=res*a%P;a=a*a%P;b>>=1;}}return res;}
template<typename T>void chmax(T& a,T b){if(a<b)a=b;return;}
template<typename T>void chmin(T& a,T b){if(a>b)a=b;return;}
const int N=1e5+10;
const char ch[3]={'w','i','n'};
int n;
string s[N];
vector<int> vec[3][3];
struct answer{
	int a[2],c[2];
};
vector<answer> ans;
answer mans(int a,int b,int c,int d){
	answer res;
	res.a[0]=a;
	res.c[0]=b;
	res.a[1]=c;
	res.c[1]=d;
	return res;
}
int get(char c){
	if(c=='w')return 0;
	if(c=='i')return 1;
	return 2;
}
void solve(){
	cin>>n;
	rep(i,3)rep(j,3)vec[i][j].clear();
	rept(i,n){
		cin>>s[i];
		int x=get(s[i][0]),y=get(s[i][1]),z=get(s[i][2]);
		if(x!=y&&y!=z&&x!=z)continue;
		if(x==y&&x==z){
			if(x!=0)vec[x][0].pb(i);
			if(x!=1)vec[x][1].pb(i);
			if(x!=2)vec[x][2].pb(i);
		}
		else{
			int u;
			if(x==y||x==z)u=x;
			else u=y;
			int v=3-x-y-z+u;
			vec[u][v].pb(i);
		}
	}
	ans.clear();
	rep(i,3){
		rep(j,3){
			if(i<j){
				while(!vec[i][j].empty()&&!vec[j][i].empty()){
					int x=vec[i][j].back(),y=vec[j][i].back();
					vec[i][j].pop_back();
					vec[j][i].pop_back();
					ans.pb(mans(x,i,y,j));
				}
			}
		}
	}
	while(!vec[0][1].empty()&&!vec[1][2].empty()&&!vec[2][0].empty()){
		int x=vec[0][1].back(),y=vec[1][2].back(),z=vec[2][0].back();
		vec[0][1].pop_back();
		vec[1][2].pop_back();
		vec[2][0].pop_back();
		ans.pb(mans(x,0,y,1));
		ans.pb(mans(y,0,z,2));
	}
	while(!vec[1][0].empty()&&!vec[0][2].empty()&&!vec[2][1].empty()){
		int x=vec[1][0].back(),y=vec[0][2].back(),z=vec[2][1].back();
		vec[1][0].pop_back();
		vec[0][2].pop_back();
		vec[2][1].pop_back();
		ans.pb(mans(x,1,y,0));
		ans.pb(mans(y,1,z,2));
	}
	cout<<sz(ans)<<"\n";
	rep(i,sz(ans)){
		cout<<ans[i].a[0]<<" "<<ch[ans[i].c[0]]<<" "<<ans[i].a[1]<<" "<<ch[ans[i].c[1]]<<"\n";
	}
}
signed main(){
	int t;
	cin>>t;
	while(t--)solve();
	return 0;
}
//Jerry_Jiang

标签:return,Exchange,int,题解,text,vec,Letter,res,define
From: https://www.cnblogs.com/Jerry-Jiang/p/17099756.html

相关文章

  • HDU5126 stars题解
    HDU5126Description\(T\)组数据,给一个空的三维空间,\(Q\)次操作,分为插入一个点和查询某个立方体内点的个数。\(T\le10,Q\le5\times10^4\)Sol题目没说强制在线......
  • CF1333F Kate and imperfection 题解 线性筛
    题目链接:http://codeforces.com/problemset/problem/1333/F题目大意:kate有一个集合S,S中的元素是1到n的整数她认为集合S的一个子集M的集合的不完美值等于\(\max_{a,b\in......
  • 消息队列的延时以及过期失效,消息队列消息积压及占满问题解决思路
    大量消息在mq里积压了几个小时了还没解决几千万条数据在MQ里积压了七八个小时,从下午4点多,积压到了晚上11点多。这个是我们真实遇到过的一个场景,确实是线上故障了......
  • CF1787I Treasure Hunt 题解
    题目链接题意描述:定义一个序列的权值为一段前缀与一段子段,满足要么前缀与子段不交,要么完全包含的和的最大值,给定一个序列\(a\),求\(a\)的所有子区间的权值和\(n\le1......
  • Django关于站点管理Admin Site的常见问题解决方法
    1.改变django默认语言的方法?仅需添加’django.middleware.locale.LocaleMiddlewar’到MIDDLEWARE_CLASSES设置中,并确保它在’django.contrib.sessions.middleware.Session......
  • CF253D Table with Letters - 2 优美枚举
    题目描述VasyahasrecentlystartedtolearnEnglish.NowheneedstorememberhowtowriteEnglishletters.Heisn'tsureaboutsomeofthem,sohedecidedtot......
  • Android 软键盘弹出时布局内指定内容上移实现及问题解决
    AndroidSDK目前提供的软键盘弹出模式接口只有两种:一是弹出时自动回冲界面,将所有元素上顶,一种则是不重绘界面,直接将控件元素遮住,没有其他模式,如果......
  • CF1137F Matches Are Not a Child's Play 题解
    以最后被删去的点为根,这样子不会存在从父亲然后删掉某个点,儿子的删除顺序一定比父亲前。记每个点子树中的最大值为\(f_x\),那么一个点的排名,首先就需要加上\(<f_x\)的所......
  • robotframe环境搭建及问题解决
     1.安装pipinstallrobotframeworkipinstallrobotframework-ride进入C:\Python37\Scripts目录下,右击ride.py,选择使用python打开。出现RIDE界面表示RIDE安装成功。......
  • ABC288 EFG 题解
    E注意到后面选对前面的答案没有影响,而且前面选的顺序对后面的影响是连续的一段(如选2个,那么对应的\(c\)就应该是\(c[i-2..i]\)(对应\(i\)是1、2、3个选时的答案))然......