CF1784B Letter Exchange 题解
前言
赛时写了
解法
本题需要使用贪心算法与双指针处理技巧。
先将所有的字符串按照
然后再按照同样的方式排序一次,将还有多余
最后按照
实现可以借助 STL 中的多元组 std::tuple。
放代码:
#include<bits/stdc++.h>
using namespace std;
typedef tuple<int,int,int,int> tpi;
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int t; cin>>t;
while(t--){
int n; cin>>n;
vector<tpi> a(n);
vector<tuple<int,char,int,char> > v;
for(int i=0;i<n;i++){
string s; cin>>s;
a[i]=make_tuple(i,count(s.begin(),s.end(),'w'),count(s.begin(),s.end(),'i'),count(s.begin(),s.end(),'n'));
} // 统计字符个数
sort(a.begin(),a.end(),[](tpi x,tpi y){return get<1>(x)==get<1>(y)?get<2>(x)>get<2>(y):get<1>(x)>get<1>(y);});
int l=0,r=n-1;
while(l<r){
if(get<1>(a[l])<2)break;
if(get<1>(a[l])==3){
char c; get<1>(a[l])--,get<1>(a[r])++;
if(get<2>(a[r])>1)get<2>(a[r])--,get<2>(a[l])++,c='i';
else get<3>(a[r])--,get<3>(a[l])++,c='n';
v.emplace_back(get<0>(a[l]),'w',get<0>(a[r]),c);
} // 有 3 个 w
else if(get<1>(a[l])==2){
char c; get<1>(a[l])--,get<1>(a[r])++;
if(get<2>(a[r])>1)get<2>(a[r])--,get<2>(a[l])++,c='i';
else get<3>(a[r])--,get<3>(a[l])++,c='n';
v.emplace_back(get<0>(a[l]),'w',get<0>(a[r]),c);
} // 有 2 个 w
else break; // 没必要继续处理
l++,r--;
} // 第一轮
sort(a.begin(),a.end(),[](tpi x,tpi y){return get<1>(x)==get<1>(y)?get<2>(x)>get<2>(y):get<1>(x)>get<1>(y);});
l=0,r=n-1;
while(l<r){
if(get<1>(a[l])<2)break;
if(get<1>(a[l])==2){
char c; get<1>(a[l])--,get<1>(a[r])++;
if(get<2>(a[r])>1)get<2>(a[r])--,get<2>(a[l])++,c='i';
else get<3>(a[r])--,get<3>(a[l])++,c='n';
v.emplace_back(get<0>(a[l]),'w',get<0>(a[r]),c);
}
l++,r--;
} // 第二轮
sort(a.begin(),a.end(),[](tpi x,tpi y){return get<2>(x)==get<2>(y)?get<3>(x)>get<3>(y):get<2>(x)>get<2>(y);});
l=0,r=n-1;
while(l<r){
if(get<2>(a[l])<2)break;
v.emplace_back(get<0>(a[l]),'i',get<0>(a[r]),'n');
l++,r--;
} // 第三轮
cout<<v.size()<<'\n';
for(auto [a,b,c,d]:v)
cout<<a+1<<' '<<b<<' '<<c+1<<' '<<d<<'\n';
}
return 0;
}