Codeforces Round #810 (Div. 2)题解(A-C)

A. Perfect Permutation

题目链接:Problem - A - Codeforces

题意:t组测试数据,每一次给一个n,要求输出一个1-n的全排列,要求i可以整除第i个元素ai的数量最少。

思路:,当i等于1时,i必能整除ai,可以将最大元素n放在第一个元素,剩余元素1-n-1对应放在2-n的位置上,这样后面的i无法整除ai。

代码实现:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e6+10;
int main()
{	
	int t;
	cin>>t;
	while(t--)
	{
		int n;
		cin>>n;
		cout<<n;//最大元素n放在第一位 
		for(int i=1;i<n;i++)//1-n-1放在位置2-n上 
		cout<<' '<<i;
		cout<<'\n';
	}
	return 0;
}

B. Party 

题目链接:Problem - B - Codeforces

题意:有一个派对,邀请n个人中部分人参加,如果第i个人没有被邀请,那么就会有不开心值ai,n个人中有m对朋友,要求被邀请的朋友的对数是偶数,求不开心值的最小值。

思路:反向思考,假设一开始所有人被邀请,观察朋友对数m当朋友对数为偶数时,那么成立,不开心值的和为0,当为奇数时,首先在记录朋友的时候同时记录每个人的度(朋友的数量),并且存储一个人的每一位朋友(像建图存边那样),,先考虑删去一个度(朋友数量)为奇数的人 ,那么肯定会去删其中不开心值最小的,然后去考虑两个度为偶数且互相为朋友的一对,如果将他们两人删去,实际上派对会少奇数个朋友,(假设一对朋友uv,他们都有偶数个朋友,u除了v之外,还剩奇数个朋友,v也如此,两点删去之后,先是出uv两点外的两组奇数个朋友删去,两个奇数的和为偶数,然后uv这对朋友也消失了,总共失去了奇数个朋友),遇上面同理,选不开心值和最小的一组。

代码实现:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1e5+10;
int a[maxn]; 
int in[maxn];
int cnt=0;
int b[maxn];
vector<int>cp[maxn];
int main()
{	ios::sync_with_stdio(false);
	cin.tie(0);
	int t;
	cin>>t;
	while(t--)
	{
		int n,m;
		cin>>n>>m;
		for(int i=1;i<=n;i++)
		cp[i].clear();	
		for(int i=1;i<=n;i++)
		cin>>a[i];
		for(int i=1;i<=m;i++)
		{
			int u,v;
			cin>>u>>v;
			cp[u].push_back(v);
			cp[v].push_back(u);
		}
		int ans=inf;
		if(m%2==0)//m为偶数的情况,可以邀请所有人 
		{
			cout<<0<<'\n';
			continue;
		}
		
		for(int i=1;i<=n;i++)
		if(cp[i].size()%2==1)//寻找有奇数个朋友的人的最小不开心值 
		ans=min(ans,a[i]);
		for(int i=1;i<=n;i++)
		{
			if(cp[i].size()%2==0)//寻找朋友为偶数个的人,并寻找他的朋友中也只有偶数个朋友的人 
			{
				for(int v:cp[i])
				{
					if(cp[i].size()%2==0)//并寻找他的朋友中也只有偶数个朋友的人
					ans=min(ans,a[i]+a[v]);
				}
			}
		}
		cout<<ans<<'\n';
	} 
	return 0;
}

C. Color the Picture

题目链接:Problem - C - Codeforces

 题意:给一个n×m的矩形,有k种颜料,每种颜料有ai个,一个颜料可以涂一格方格,问是否能构建一幅美丽的画,一幅美丽的画被定义为一个方格周围至少有3个格子和他颜色相同,同时,定义第1行和 第n行,第1列和第m列是相邻的。 

思路:首先,一列必须涂同一种颜色,否则就无法满足条件,其次,对于一列同一颜色,在该列两边必须至少存在与这列颜色相同的一列。否则也无法满足条件。对n行m列的网格,考虑m的奇偶性,如果偶数,那么每次选取可以涂至少两列的颜料(ai/n>=2)即可,对于奇数,每次选取(ai/2>=2)的颜料的同时,必须至少有一个(ai/2>=3)的颜料,因为如果只有“只能涂两列”的颜料,会空出一列,而单单一列不可能能满足条件。无需考虑一种颜料(ai/2>=3)占用多列而影响其他颜料的情况,因为一种颜料可以涂x列并且x>=3是,x可以任意转化成2-x列。此外,考虑网格还可以立起来,n行m列变成m行n列,也要考虑有无可能满足条件。

代码实现:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1e5+10;
int a[maxn];
int main()
{	ios::sync_with_stdio(false);
	cin.tie(0);
	int t;
	cin>>t;
	while(t--)
	{
		int n,m,k;
		cin>>n>>m>>k;
		for(int i=1;i<=k;i++)
		cin>>a[i];
		//n行m列 
			ll ans=0;//记录能涂多少列 
			bool f=0;
			bool f2=0;
			bool f3=0;
			for(int i=1;i<=k;i++)
			{
				if(a[i]/n>=2)//选取能涂大于等于2列的颜料 
				{
					if((a[i]/n)>=3)//寻找是否有能涂大于等于3列的颜料,应对列数为奇数的条件 
					f2=1;
					ans+=(a[i]/n);
				}
			}
			if(m%2==0)//当列数为偶数时 
			{
				if(ans>=m)
				f=1;
			}
			else//当列数为奇数时 
			{
				if(ans>=m&&f2)
				f=1;
			}
			//m行n列的情况 
			ans=0;
			for(int i=1;i<=k;i++)
			{
				if(a[i]/m>=2)//选取能涂大于等于2列的颜料 
				{
					if((a[i]/m)>=3)//寻找是否有能涂大于等于3列的颜料,应对列数为奇数的条件 
					f3=1;
					ans+=(a[i]/m);
				}
			}
			if(n%2==0)//当列数为偶数时 
			{
				if(ans>=n)
				f=1;
			}
			else
			{
				if(ans>=n&&f3)//当列数为奇数时 
				f=1;
			}
			if(f)
			cout<<"Yes\n";
			else
			cout<<"No\n"; 
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值