牛客周赛 Round 131 题解

A.ICPC Balloons

分情况模拟即可。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define Int long long
#define itn long long
#define iint long long

string s;
inline int read() {
	int x = 0, f = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 3) + (x << 1) + (ch ^ 48);
		ch = getchar();
	}
	return x * f;
}
inline void write(int x) {
	if (x < 0) {
		putchar('-');
		x = -x;
	}
	if (x > 9)
		write(x / 10);
	putchar(x % 10 + '0');
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin>>s;
	if(s[0]=='A') cout<<"red";
	else if(s[0]=='B') cout<<"orange";
	else if(s[0]=='C') cout<<"blue";
	else cout<<"green";
	return 0;
}

B.String Covering

很显然若有 ,且 就不行。

模拟判断即可,时间复杂度为 ,不给代码。

C.Get The Sequence

假设当前处理 这两个数字,当前就分两种情况:

  1. ,就说明 可以通过疯狂减 得到,不需要额外操作。
  2. 就说明当前的 匹配不上,必须删掉,下一次就是 匹配。

可以注意到上列过程可以通过双指针实现,时间复杂度为 ,具体如下:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define Int long long
#define itn long long
#define iint long long
const int N=2e5+10;
int n,m,a[N],b[N],f[N];
inline int read() {
	int x = 0, f = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 3) + (x << 1) + (ch ^ 48);
		ch = getchar();
	}
	return x * f;
}
inline void write(int x) {
	if (x < 0) {
		putchar('-');
		x = -x;
	}
	if (x > 9)
		write(x / 10);
	putchar(x % 10 + '0');
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	int T;
	cin>>T;
	while(T--){
		memset(f,0,sizeof(f));
		cin>>n>>m;
		for(int i=1;i<=n;i++) cin>>a[i];
		for(int i=1;i<=m;i++) cin>>b[i];
		int i=1,j=1;
		while(i<=n&&j<=m){
			if(a[i]>=b[j]){
				i++;
				f[j]=1;
				j++;
			}else i++;
		}
		bool f1=1;
		for(int i=1;i<=m;i++){
			if(f[i]==0){
				f1=0;
				break;
			}
		}
		if(f1) cout<<"YES\n";
		else cout<<"NO\n";
	}
	return 0;
}

D.Longest Subsequence

可以发现,此题存在一个十分朴素的 trick,就是最长上升子序列,具体就不详细展开,时间复杂度为 ,具体如下:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define Int long long
#define itn long long
#define iint long long
const int N=2e5+10;
int n,a[N],dp[N];
inline int read() {
	int x = 0, f = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 3) + (x << 1) + (ch ^ 48);
		ch = getchar();
	}
	return x * f;
}
inline void write(int x) {
	if (x < 0) {
		putchar('-');
		x = -x;
	}
	if (x > 9)
		write(x / 10);
	putchar(x % 10 + '0');
}
void solve(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i],dp[i]=1;
	for(int i=1;i<=n;i++){
		for(int j=1;j<i;j++){
			if(abs(a[i]-a[j])==1) dp[i]=max(dp[i],dp[j]+1);
		}
	}
	int maxn=1;
	for(int i=1;i<=n;i++) maxn=max(maxn,dp[i]);
	cout<<maxn<<"\n";
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	int T;
	cin>>T;
	while(T--){
		solve();
	}
	return 0;
}

赛时提交代码 分。

现在考虑优化。

我们设 为以 这个数为结尾的最长子序列长度,可以发现 只能从 转移而来,存在转移 ,时间复杂度为

具体如下:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,a[N],dp[N];
void solve(){
	cin>>n;
	memset(dp,0,sizeof(dp));
	for(int i=1;i<=n;i++) cin>>a[i];
	int ans=0;
	for(int i=1;i<=n;i++){
		int x=a[i];
		int cur=max(dp[x-1],dp[x+1])+1;
		dp[x]=max(dp[x],cur);
		ans=max(ans,cur);
	}
	cout<<ans<<"\n";
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	int T;
	cin>>T;
	while(T--) solve();
	return 0;
}

E.Eat The Candy

存在一个很简单的想法,就是枚举 为那个糖果最多的盒子,统计它能被执行操作多少次,答案就是操作数加上

那操作数怎么算呢?

我们假设要统计 的操作数,最暴力的贪心做法就是从 扫到 ,看每个 能执行多少次,最后累加答案,时间复杂度为

优化也很简单,用一个前缀数组 和一个后缀数组 预处理即可,存在转移 ,答案为 ,具体如下:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define Int long long
#define itn long long
#define iint long long
const int N=2e5+10;
int n,a[N],f[N],g[N],b[N],c[N];
inline int read() {
	int x = 0, f = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 3) + (x << 1) + (ch ^ 48);
		ch = getchar();
	}
	return x * f;
}
inline void write(int x) {
	if (x < 0) {
		putchar('-');
		x = -x;
	}
	if (x > 9)
		write(x / 10);
	putchar(x % 10 + '0');
}
void solve(){
	cin>>n;
	memset(f,0,sizeof(f));
	memset(g,0,sizeof(g));
	int ans=0;
	for(int i=1;i<=n;i++) cin>>a[i],b[i]=a[i],c[i]=a[i];
	for(int i=2;i<=n;i++) f[i]=f[i-1]+min(b[i],b[i-1]),b[i]-=min(b[i],b[i-1]);
	for(int i=n-1;i>=1;i--) g[i]=g[i+1]+min(c[i],c[i+1]),c[i]-=min(c[i],c[i+1]);
	for(int i=1;i<=n;i++) ans=max(ans,a[i]+f[i-1]+g[i+1]);
	cout<<ans<<"\n";
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	int T;
	cin>>T;
	while(T--) solve();
	return 0;
}
全部评论

相关推荐

哞客37422655...:这就是真实社会,没有花里胡哨的安慰,让你感受到阶级分明,不浪费彼此时间。虽然露骨但是唉
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务