专栏文章

CF2130B Pathless

CF2130B题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miog6abd
此快照首次捕获于
2025/12/02 18:40
3 个月前
此快照最后确认于
2025/12/02 18:40
3 个月前
查看原文

题目传送门

思路

我们设原数组 aa 的各个数之和为 sumsum
  1. sum>ssum > s,因为每个数字都会被访问,所以数值和一定会超过 ss,输出原数组即可。
  2. sum=ssum = s,此时不管怎样排列数组,只要从 11 走到 nn 就一定合法,此时输出 1-1
  3. ssum=1s - sum = 1,当原数组存在相邻的 0011 就一定合法(折返),所以我们要避免出现相邻的 0011,可以将 22 放在 0011 之间,即先输出所有的 00,再输出所有的 22,最后输出所有的 11
  4. ssum>1s - sum > 1,和上种情况类似,如果出现相邻的 0011,就可以不停地折返 +1+1。所以还是要将 22 放在 0011 之间。此时会出现相邻的 0022,以及相邻的 2211,其折返一次的贡献分别为 2233,可以证明这两种贡献可以组成任意多的贡献。此时无解,输出 1-1

AC Code

CPP
#include <bits/stdc++.h>
using namespace std;
const int N=50+5;
int a[N];
void solve()
{
	int n,s;
	cin >>n>>s;
	int cnt0=0,cnt1=0,cnt2=0;
	long long sum=0; 
	for(int i=1;i<=n;i++)
	{
		cin >>a[i];
		sum+=a[i];
		if(a[i]==0) cnt0++;
		if(a[i]==1) cnt1++;
		if(a[i]==2) cnt2++;
	}
	if(sum>s)
	{
		for(int i=1;i<=n;i++) cout <<a[i]<<" ";
	}
	else if(sum==s || s-sum>1) cout <<-1;
	else
	{
		for(int i=1;i<=cnt0;i++) cout <<0<<" ";
		for(int i=1;i<=cnt2;i++) cout <<2<<" ";
		for(int i=1;i<=cnt1;i++) cout <<1<<" ";
	}
	cout <<'\n';
}
int main()
{
	int t;
	cin >>t;
	while(t--) solve(); 
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...