Codeforces Round 950 (Div. 3)

4 篇文章 0 订阅

A. Problem Generator

题意:

弗拉德计划在下个月举行 m m m 轮比赛。每轮比赛应包含一个难度为"A"、“B”、“C”、“D”、“E”、"F "和 "G "的问题。弗拉德已经有了一个 n问题库,其中 i /th问题的难度为 ai 。这些问题可能不够多,所以他可能需要再想出一些问题。弗拉德想要尽可能少地提出问题,所以他要求你找出他需要提出的问题的最小数量,以便举行 m轮比赛。

题解:

用map记录每个字母出现的次数,然后判断需要添加几个够m个,求和就是答案。

代码:

#include<iostream>
#include<algorithm>
#include<map>
 
using namespace std;
 
void solve(){
	int n,m;
	map<char,int> mp;
	cin>>n>>m;
	
	string s;
	
	cin>>s;
	
	for(int i=0;i<(int)s.size();i++) mp[s[i]]++;
	
	int ans=0;
	
	for(int i=0;i<7;i++){
		char temp=char(i+'A');
		int x=(m-mp[temp]);
		if(x<0) continue;
		ans+=x;
	}
	cout<<ans<<endl;
}
int main(){
	int t;
	
	cin>>t;
	
	while(t--) solve();
	
	return 0;
}

B. Choosing Cubes

题意:

有n个元素数组 a a a,德米特喜欢第f个元素,然后数组会进行从大到小排序,然后将前k个元素删除,若德米特最爱的元素在所有情况下都会被移除,则输出 y e s yes yes;如果在任何情况下都不会被移除,则输出 n o no no;如果可能会被移除或留下,则输出 M A Y B E MAYBE MAYBE

题解:

记录排序前第f个元素的值,以及数组中每个值的元素共有多少个,然后将数组排序,将前k个元素出现次数减去,观察f的出现次数如何变化,若不变则输出 n o no no,若变为0,则输出 y e s yes yes,若减少但不为0.则输出 M A Y B E MAYBE MAYBE

代码:

#include<iostream>
#include<algorithm>
#include<map>

using namespace std;

const int N=110;
int a[N],b[N];

void solve(){
	int n,f,k;
	map<int,int> mp;
	
	cin>>n>>f>>k;
	
	for(int i=1;i<=n;i++) cin>>a[i],b[i]=a[i],mp[a[i]]++;
	
	int temp=a[f];
	int x=mp[temp];
	sort(a+1,a+1+n, greater<int>());
	for(int i=1;i<=k;i++){
		mp[a[i]]--;
	}
	int y=mp[temp];
	if(y==0) cout<<"YES"<<endl;
	else if(y<x&&y>0) cout<<"mAyBe"<<endl;
	else if(x==y) cout<<"No"<<endl;
}
int main(){
	int t;
	
	cin>>t;
	
	while(t--) solve();
	
	return 0;
}

C. Sofia and the Lost Operations

题意:

有一个由 n n n 个整数 a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1,a2,,an 组成的数组。对它进行 m m m 修改操作。

每个修改操作都由一对数字 ⟨ c j , d j ⟩ \langle c_j, d_j \rangle cj,dj 来描述,这意味着数组中索引为 c j c_j cj 的元素应该被赋值 d j d_j dj ,即执行赋值 a c j = d j a_{c_j} = d_j acj=dj
你发现了一个由 n n n 个整数 b 1 , b 2 , … , b n b_1, b_2, \ldots, b_n b1,b2,,bn 组成的数组。你想知道这个数组是否是m次操作后的数组。你知道原始数组的值以及 d 1 , d 2 , … , d m d_1, d_2, \ldots, d_m d1,d2,,dm 的值。结果发现数值 c 1 , c 2 , … , c m c_1, c_2, \ldots, c_m c1,c2,,cm 丢失了。
问是否存在一个序列 c 1 , c 2 , … , c m c_1, c_2, \ldots, c_m c1,c2,,cm 使得对数组 a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1,a2,,an 的修改操作 ⟨ c 1 , d 1 , ⟩ , ⟨ c 2 , d 2 , ⟩ , … , ⟨ c m , d m ⟩ \langle c_1, d_1, \rangle, \langle c_2, d_2, \rangle, \ldots, \langle c_m, d_m \rangle c1,d1,,c2,d2,,,cm,dm连续应用将其转换为数组 b 1 , b 2 , … , b n b_1, b_2, \ldots, b_n b1,b2,,bn

题解:

只有当 a i a_{i} ai!= b i b_{i} bi时,都存在一个 d j d_{j} dj= b i b_{i} bi,且d数组的最后一个数组和b数组的其中一个元素相同时,才满足可以转换,否则不可以。

代码:

#include<iostream>
#include<algorithm>
#include<map>
#define int long long
 
using namespace std;
 
const int N=2e5+10;
int a[N],b[N],d[N];
 
void solve(){
	int n;
	map<int,int> mp;
	map<int,int> temp;
	cin>>n;
	
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++) cin>>b[i],temp[b[i]]++;
	
	int m;
	
	cin>>m;
	
	for(int i=1;i<=m;i++) cin>>d[i],mp[d[i]]++;
	
	int flag=1;
	
	for(int i=1;i<=n;i++){
		if(a[i]!=b[i]) flag=0;
	}
	if(flag){
		if(temp[d[m]]) cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
		return;
	}
	for(int i=1;i<=n;i++){
		if(a[i]!=b[i]){
			mp[b[i]]--;
			if(mp[b[i]]<0){
				cout<<"NO"<<endl;
				return;
			}
		}
	}
	if(temp[d[m]]==0){
		cout<<"NO"<<endl;
		return;
	}
	cout<<"Yes"<<endl;
}
signed main(){
	int t;
	
	cin>>t;
	
	while(t--) solve();
	
	return 0;
}

D. GCD-sequence

题意:

给定一个含有 n n n个元素的数组,每两个相邻的元素求一个 g c d gcd gcd,将每次求得 g c d gcd gcd构成一个数组 b b b,问b是否是一个不递减的数组,若不是是否可以在 a a a中删除一个元素,重新求得 b b b为不递减。

题解:

先遍历数组 a a a,求出数组 b b b,然后针对递减的点 i i i,分别尝试删除 a i − 1 a_{i-1} ai1 a i a_{i} ai a i + 1 a_{i+1} ai+1,看着三种删除方法是否可以使得b不递减。

代码:

#include<iostream>
#include<algorithm>
#include<math.h>

#define int long long

using namespace std;

const int N=2e5+10;
int a[N],b[N],c[N];
int n;

bool check(int idx) {
	copy(a + 1, a + idx, c + 1);
	copy(a + idx + 1, a + n + 1, c + idx);

	int m = n - 1;
	for (int i = 1; i < m; ++i) b[i] = __gcd(c[i], c[i + 1]);
	for (int i = 2; i < m; ++i) {
		if (b[i - 1] > b[i]) return false;
	}
	return true;
}

bool solve(){
	
	cin>>n;
	
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<n;i++) b[i]=__gcd(a[i+1],a[i]);
	
	for(int i=2;i<n;i++)
		if(b[i-1]>b[i]) return check(i-1)||check(i)||check(i+1);
	
	return true;
}

signed main(){
	int t;
	
	cin>>t;
	
	while(t--){
		if(solve()) cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
	}
	
	return 0;
}

E. Permutation of Rows and Columns

题意:

给出两个n*m的矩阵 a a a b b b,每次操作可以选取两行或者两列进行交换,问是否可以对矩阵 a a a进行有限次操作将 a a a变成矩阵 b b b

题解:

交换两行操作只会影响到重排行的位置,原来在同一行的元素也还在同一行,在同一列的也是如此。交换两列操作也是这样,所以只需要判断对于 a a a矩阵的每一行 b b b矩阵中是否存在与其元素相同的行, a a a矩阵的每一列 b b b矩阵中是否存在与其元素相同的列。

代码:

#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;
#define ll long long int
bool cmp(vector<int>& x,vector<int>& y)
{
	return x[0]<y[0];
}
bool f(vector<vector<int>> a,vector<vector<int>> b,int n,int m)
{
	for(int i=0;i<n;i++)
	{
		sort(a[i].begin(),a[i].end());
		sort(b[i].begin(),b[i].end());
	}
	sort(a.begin(),a.end(),cmp);
	sort(b.begin(),b.end(),cmp);
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			if(a[i][j]!=b[i][j])
				return true;
		}
	}
	return false;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	int t;
	cin>>t;
	while(t--)
	{
		int n,m;
		cin>>n>>m;
		vector<vector<int>> a(n,vector<int>(m)),b(n,vector<int>(m));
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
				cin>>a[i][j];
		}
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
				cin>>b[i][j];
		}
		vector<vector<int>> ta(m,vector<int>(n)),tb(m,vector<int>(n));
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				ta[j][i]=a[i][j];
				tb[j][i]=b[i][j];
			}
		}
		if(f(a,b,n,m)||f(ta,tb,m,n))
			cout<<"NO"<<endl;
		else
			cout<<"YES"<<endl;
	}
}

  • 20
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值