Codeforces Round #829 (Div. 2)——A、B、C1、D

A:

 题意:给定一个由QA组成的字符串,Q表示问题,A表示回答,要求每一个Q后面都能对应至少一个A。

方法:栈。我们发现,只有一个Q后面有一个A就行,多个A无所谓,那么QQ就需要后面两个A。所以,我们用ans记录Q的个数,在每个Q后面遇见A,就减去一个Q的个数,最后判断还有没有Q,如果没有则说明,合法,否则非法。

代码:

#include<bits/stdc++.h>
using namespace std;
string s;
int n;
inline void solve(){
	cin>>n>>s;
	int ans=0;
	for(int i=0;i<s.size();i++){
		if(s[i]=='Q') ans++;
		else ans--;
		if(ans<0) ans=0;
	}
	if(ans) cout<<"NO\n";
	else cout<<"YES\n";
}

int main(){
	int T;cin>>T;
	while(T--) solve();
}

B:

 题意:给定数组长度n,请构造一个排列使得两个相邻元素差的最小值最大。

方法:因为是构造题。所以我猜的最大值是n/2,但是确实构造的差值就是n/2。如果我们构造(1,n),(2,n-1),最终会发现差值为1,肯定不是最大值。然后再考虑(1,n/2),(2,n/2+1),这样发现确实是可行的。如果n是奇数,我们就把第n个数放在前面即可

代码:

#include<bits/stdc++.h>
using namespace std;

inline void solve(){
	int n;cin>>n;
	int k=n/2;
	for(int i=k;i;i--)
		for(int j=i;j<=n;j+=k)
			cout<<j<<" ";
	cout<<"\n";	
	
}

int main(){
	int T;cin>>T;
	while(T--) solve();
}

C1: 

 题意:给一个只包含1和-1的数组,区间[L , R]的价值为a[l] - a[l+1] + a[l+2] ……+(-)a[r]

求一个划分,使得每个区间的价值之和为0 , 不需要最小化划分数

思路:我们发现,当数组长度是奇数的时候,不管怎样划分都不可能成功。当为偶数的时候,我们只需要从左往右两个元素两个元素的看。如果两个元素是一样的,就划分为一组,如果不一样,就各自划分一组。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=2e5+10;
int a[N];

inline void solve(){
	int n;cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	if(n%2==1){
		cout<<"-1\n";return;
	}
	vector<PII>v;
	for(int i=1;i<=n;i+=2){
		if(a[i]==a[i+1]) v.push_back({i,i+1});
		else{
			v.push_back({i,i});
			v.push_back({i+1,i+1});
		}
	}
	cout<<v.size()<<"\n";
	for(auto i:v){
		cout<<i.first<<" "<<i.second<<"\n";
	}
}

int main(){
	int T;cin>>T;
	while(T--) solve();
}

D:

 题意:给定一个长度为n的数组和k,判断k!是否整除(a1! + a2! + a3! + a4!... + an!)

 方法:首先,这道题是肯定不能暴力的。一开始我以为是找因子,简要的思绪并没有取得满意的结果。后面看了看别人的题解,发现确实很巧妙。分析:

map来统计每一个数出现的次数,我们发现一个数字出现的次数可以累加到这个数的上一位。比如出现了5个4,那么这5个4就可以形成一个5的倍数,相当于多出现了一个5。我们从低位往高位累加,判断mp[i] % (i + 1)是否等于0,如果不等于0一定无解。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10;
int a[N],mp[N];

inline void solve(){
	int n,k;cin>>n>>k;
	for(int i=1;i<=n;i++) cin>>a[i],mp[a[i]]++;
	
	for(int i=1;i<k;i++){
		if(mp[i]%(i+1)){
			cout<<"NO";return;
		}
		mp[i+1]+=mp[i]/(i+1);
	}
	cout<<"YES";
}

int main(){
	 solve();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值