CodeTON Round 7 (Div. 1 + Div. 2, Rated, Prizes!)

A. Jagged Swaps

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N=15;
int a[N];
int n;
void solve() {
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	if(a[1]==1) cout<<"Yes"<<endl;
	else cout<<"No"<<endl;
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t=1;
    cin>>t;
	while(t--) {
		solve();
	}
	return 0;
}

B. AB Flipping

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
int n;
string s;
void solve() {
	cin>>n;
	cin>>s;
	bool ok=false;
	for(int i=0;i<n-1;i++){
		if(s[i]=='A'&&s[i+1]=='B'){
			ok=true;
			break;
		}
	}
	int cnt1=0,cnt2=0;
	for(int i=0;i<n;i++){
		if(s[i]=='B') cnt1++;
		else break;
	}
	for(int i=n-1;i>=0;i--){
		if(s[i]=='A') cnt2++;
		else break;
	}
	if(ok) cout<<n-1-cnt1-cnt2<<endl;
	else cout<<0<<endl;
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t=1;
    cin>>t;
	while(t--) {
		solve();
	}
	return 0;
}

C. Matching Arrays

长度为n的数组a和b,数[1,2*n]

重新排列b,使得ai大于bi的个数刚好为x,无解输出No

贪心,a中x个最大的和b中x个最小的匹配,先保证有x个,并不是a中最大的和b中最小的,而是a中x个最大的升个序,b中x个最小的升个序,然后按顺序匹配,剩下的同理,为什么要升序后按顺序比,可以通过反向思考来感受这样做的合理性

trick:

1.贪心的思考方式:通过反向思考来感受贪心是否合理

2.两两匹配问题

分为三种

第一种是序列内部进行两两匹配,比如说最小和最大匹配,次小和次大匹配

第二种是两个不同的序列进行匹配,比如说每次匹配差值最大的,要么序列a的最大和序列b的最小匹配,要么序列a的最小和序列b的最大匹配,再比如说要求是ai大于bi刚好有x个,那么需要a中最大的x个去和b中最小的x个匹配,保证有x个,但不是a的最大和b的最小匹配,而是分别升序,然后按顺序匹配,合理性通过反向思考感受

第三种是两个一样的序列进行匹配,一般是通过自身元素的两两交换来满足某个要求,本质上就是自身和自身匹配

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
typedef pair<int,int>PII;
const int N=2e5+10;
int a[N];
int n,xx;
void solve() {
	cin>>n>>xx;
	vector<PII>ans;
	for(int i=0;i<n;i++){
		int x;
		cin>>x;
		ans.push_back({x,i});
	}
	multiset<int>s;
	multiset<int,greater<int>>s1,s2;
	for(int i=0;i<n;i++){
		int x;
		cin>>x;
		s.insert(x);
	}
	sort(ans.begin(),ans.end());
	reverse(ans.begin(),ans.end());
	for(int i=0;i<xx;i++){
		s1.insert(*s.begin());
		s.erase(s.begin());
	}
	while(s.size()){
		s2.insert(*s.begin());
		s.erase(s.begin());
	}
	for(int i=0;i<xx;i++){
		if(*s1.begin()>=ans[i].first){
			cout<<"No"<<endl;
			return;
		}
		a[ans[i].second]=*s1.begin();
		s1.erase(s1.begin());
	}
	for(int i=xx;i<n;i++){
		if(*s2.begin()<ans[i].first){
			cout<<"No"<<endl;
			return;
		}
		a[ans[i].second]=*s2.begin();
		s2.erase(s2.begin());
	}
	cout<<"Yes"<<endl;
	for(int i=0;i<n;i++) cout<<a[i]<<' ';
	cout<<endl;
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t=1;
    cin>>t;
	while(t--) {
		solve();
	}
	return 0;
}
  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值