【CF | Good Bye 2021: 2022 is NEAR】A—D

A - Integer Diversity

题意:略

题解:引入一个数组记录绝对值出现次数,普通最多有效两次,特判0最多一次。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e3+3;
int a[maxn];
int b[maxn];
int main() {
	int t;cin>>t;
	while(t--){
		int n;cin>>n;
		int x;
		int sum=0;
		memset(a,0,sizeof(a));
		for(int i=0;i<n;i++){
		   cin>>x;
		   x=abs(x);
		   a[x]++;
		   if(x==0&&a[x]==1)sum++;
		   else if(x!=0&&a[x]<=2)sum++;	
		}
		cout<<sum<<endl;
	}
	
	return 0;
}

B - Mirror in the String

题意:
找出最小的镜像字符串
一个小问题:对最小字符串的理解,不是越短越好,还得看字典序。这个导致题目意思刚开始没看明白。

题解:
非递增则一直向下找,直到找到一个后大于前的,停止镜像。
特判:如果是第一个位置和第二个位置出现相等,则只需输出第一个位置和镜像。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e3+3;
int a[maxn];
int b[maxn];
int main() {
	int t;cin>>t;
	while(t--){
		int n;cin>>n;;
		string s;cin>>s;
		int f=0;
		cout<<s[0];
		for(int i=0;i<s.size()-1;i++){
			if(s[i]>s[i+1])cout<<s[i+1];
			else if(i!=0&&s[i]==s[i+1])cout<<s[i+1];
			else {
				for(int j=i;j>=0;j--)cout<<s[j];
				f=1;
				break;
			}
		}
		if(f==0){
			for(int j=s.size()-1;j>=0;j--)cout<<s[j];
		}
		cout<<endl;
	}
	
	return 0;
}

Representative Edges

题意:
要求每个子序列都满足这个公式:
在这里插入图片描述
求最小操作数。

题解:
可以看出这个公式是等差数列的求和公式。
然后给的数据是非常少的。
那么我们只需枚举任意两个数,计算首项和公差就可以推出每一个位置应该是什么,如果不是,则需要操作一次。记录最小操作数。

注意:wa死我了,精度问题!!
1》加减法代替乘法
2》判断相等用差值小于1e-6

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e3+3;
double a[maxn],b[maxn];
int main() {
	int t;cin>>t;
	while(t--){
		int n;cin>>n;
		for(int i=1;i<=n;i++)cin>>a[i];
		int cnt=0;
		int mcnt=n;
		for(int ii=1;ii<n;ii++){
			for(int jj=ii+1;jj<=n;jj++){
				cnt=0;
				double d=(a[jj]-a[ii])/(jj-ii);
				double a1=a[ii]-(ii-1)*d;
				for(int i=1;i<=n;i++)b[i]=a[i];
				for(int i=ii+1;i<=n;i++){
					if(i==jj)continue;
					if(abs(b[i]-(b[i-1]+d))>1e-6)b[i]=b[i-1]+d,cnt++;
				}
				for(int i=ii-1;i>0;i--){
					//if(i==jj)continue;
					if(abs(b[i]-(b[i+1]-d))>1e-6)b[i]=b[i+1]-d,cnt++;
				}
				mcnt=min(mcnt,cnt);
			}
		}
		if(n<=2)cout<<0<<endl;
		else 
	        cout<<mcnt<<endl;
	}
		
	return 0;
}

D. Keep the Average High

题意:
找最大的选择数,需满足以下条件:
对任意子序列(不含单个元素),必须满足二者至少一个
1》:有未选择的
2》在这里插入图片描述
题解:
对于2,根据c公式的启发,将不等号右边的拆开,与左边的匹配,一一减去。此时,该公式含义转化为在原序列上求一个序列,该序列的原有顺序不变,但是不能出现连续子序列小于0的情况。单个元素不算。
然后写一下大小关系能看出,只用判断长度为2、3的子序列符合非负。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e5+3;
int a[maxn];
#define sc scanf
#define pr printf
int main() {
	int t;cin>>t;
	while(t--){
		int n;cin>>n;
		for(int i=1;i<=n;i++)sc("%d",&a[i]);
		int x;cin>>x;
		int last=1,cnt=0;
		for(int i=1;i<=n;i++){
		   a[i]-=x;
		if(i>last&&a[i]+a[i-1]<0){
		last=i+1;
		continue; 
		}
		if(i>last+1&&a[i]+a[i-1]+a[i-2]<0) {
		last=i+1;
		continue;
		}
		cnt++;
		}
		cout<<cnt<<endl;
	}
		
	return 0;
}```

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值