Codeforces Round 905 (Div. 3)补题报告

Codeforces Round 905 (Div. 3)补题报告

A.Morning

你需要输入 个四位数密码,每次输入时你的光标都在第一个数 上,在一秒内你有两种操作:
按下光标输入一位密码。
将光标移到任意与当前数字相邻的数字。
计算输入给定密码需要的最少秒数。

我们先将sum置为4,然后拆分每一位,当前这位减去他前面这位,就是需要的时间,注意0要特判,将0位变成10
第一位是用他减去1

#include<bits/stdc++.h>
using namespace std;
int abs(int a){
	if(a<0){
		return -a;
	}
	else{
		return a;
	}
}
int main(){
	int t;
	cin>>t;
	int sum=4;
	while(t--){
	    sum=4;
		int n;
		cin>>n;
		int a,b,c,d;
		d=n%10;
		c=n/10%10;
		b=n/10/10%10;
		a=n/10/10/10%10;
		int e=1;
		if(a==0){
		    a=10;
		}
		if(b==0){
		    b=10;
		}
		if(c==0){
		    c=10;
		}
		if(d==0){
		    d=10;
		}
		sum+=abs(a-e);
		sum+=abs(b-a);
		sum+=abs(c-b);
		sum+=abs(d-c);
		cout<<sum<<endl;
	}
	return 0;
}

B.Chemistry

给定一个字符串 ,它的长度为 ,请问能否在删除 个字符后,对字符串重新排列(任意排列)使得其成为回文字符串?

当其字符为偶数个时,一定可以可以成为回文串;当其字符为奇数个时,只有最中间的一个字符可以构成回文串,其余的都要被删除。所以就遍历一遍,找出奇数字符的数量,如果大于k+1,那么无解,否则有解。

#include<bits/stdc++.h>
using namespace std;
int t,n,m,num[50],ans;
char s[100005];
int main()
{
cin >> t;
while(t--)
{
cin >> n >> k >> s;
ans = 0;
for(int i=0;i<n;i++) num[s[i]-'a']++;//统计每个字符出现的个数
for(int i=0;i<26;i++)
{
if(num[i]%2==1) ans++;
num[i]=0;
}
if(ans-1<=m) cout <<"YES"<<endl;
else cout <<"NO" << endl;
}
return 0;
}

C.Raspberries

有一个长度为 的数组 和一个整数 ( ),你每次操作可以对数组内的任意一个数加 。如果要使得 (累乘:数组中所有数字的乘积)能被数组中所有数字的乘积整除,最小操作步数是多少?

只要a数组中有一个数字能被k整除,那么数组中所有数字的乘机能被k整除。
k的数字范围是2到5,4是一个需要特判的数,其他数只要a[i]可以被整除,就可以,而4需要特判,只要数组中有超过两个数可以被2整除,则整个数组的乘积也可以被4整除。

#include <bits/stdc++.h>
using namespace std;
int n,k;
int a[N];
void solve()
{
cin >> n >> k;
int cnt = 0;
for (int i = 0; i < n; ++i) cin >> a[i];
int ans = 1e9;
for (int i = 0; i < n; i ++)
{
int t = k - (a[i] + k) % k;
if((a[i] % k) == 0) t = 0;
ans = min(ans,t);
}
if(k == 4)
{
for (int i = 0; i < n ; i ++)
if(a[i] % 2==0) cnt ++;//统计偶数的个数
if(cnt >= 2) ans = 0; //偶数个数大于等于2 更新答案
else if(n!=1 && cnt==1) ans = min(ans, 1); //n不等于1,且偶数个数等于1,则只
需要将一个奇数变为偶数即可
else if(n-cnt >= 2) ans = min(ans,2) ;//有多个奇数,将两个奇数变为偶数即可
}
cout << ans << endl;
}
int main()
{
int t;cin >> t;
while(t --) solve();
return 0;
}

D.In Love

你有 次操作,每次操作分为两种:

  1. ,表示添加一条区间范围为 的线段。
  2. ,表示删除一条区间范围为 的线段。
    问每次操作后是否存在两条线段,使得它们的区间范围没有交集。

因为题目是否两条线段是否有交集,所以我们只需要判断最左面的一个右端点,和最右面的一个左端点比较即可
在这里我们可以用到 里面的 自动排序的特性存储线段的左右端点进行增删操作。(排序不去重)

#include<bits/stdc++.h>
using namespace std;
multiset<int> L,R;
void solve() {
char op;
int l, r;
cin >> op >> l >> r;
if(op == '+') L.insert(l), R.insert(r);
else L.erase(L.find(l)), R.erase(R.find(r));
if(L.size() && *R.begin() < *L.rbegin())
puts("YES");
else puts("NO");
}
int main()
{
int t;
cin >> t;
while(t--) solve();
return 0;
}

后面的题老师没讲

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值