[cf] Codeforces Round #759 (Div. 2) ABC

前言

显然是掉分了 h h hh hh
传送门 :

A. flower

三个条件

  • 连续两个 1 1 1,那么当前的 a n s + 5 ans+5 ans+5
  • 只有一个 1 1 1,那么当前的 a n s + 1 ans+1 ans+1
  • 连续两个 0 0 0, a n s = 0 ans = 0 ans=0

因为数据范围很小,直接模拟即可

题目意思理解错了,WA了一发

const int N  = 1e5+10;
int n;
int a[N];
 
void solve()
{
	cin>>n;
	
	int sum = 1;
	
	for(int i=1;i<=n;i++)
		cin>>a[i];
		
	int flag = 0 ;
	
	for(int i = n;i>= 2;i --){
		
		if(a[i]  && a[i-1])
		sum+=5;
		else
		if(a[i])
		sum++;
		
		if(!a[i]&& !a[i-1]){
			cout<<-1<<endl;
			return;
		}
	}
	
	if(a[1] == 1)
	sum++;
	
	cout<<sum<<endl;
	
}

B.Array

给你一个数组,每次将比 x n x_n xn的数,大的按照原有顺序放到右边,否则放到左边
问多少次该操作之后,使得数组不会再变化

显然的 : 数组最大值在末尾的时候是不会在变化的

又因为 : 每次变换,相对位置不变,都是根据原有的位置

所以我们可以想到,我们每次其实都是拿比 x n x_n xn最后一个大的数

(差点歪成二分,幸好数据范围友善

因为每次拿的都是比 x n x_n xn大的一个数,我们只需要从后往前扫一遍即可,如果找到了

比当前大的,我们直接更新maxn,当找到最大值的时候,我们输出答案就行

当然如果没有答案,那么我们直接输出 0 0 0

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

void solve()
{
	cin>>n;
	int find = 0 ;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		find = max(find,a[i]);
	}
	
	int maxn = a[n];
	int ans = 0 ;
	
	for(int i = n - 1;i>=1;i -- ){
		if(a[i] > maxn){
			++ans;
			if(a[i] == find){
				cout<<ans<<endl;
				return;
			}else  maxn = a[i];
		}
	}
	cout<<0<<endl;
}

C.Distance

给你一个 x x x轴上的多个点,你可以从 0 0 0点运送物资到给定的点中,每次你只可以运

k k k个物资,问你最少需要运送多长的 x i − 0 x_i - 0 xi0的距离

显然的 : 我们从尾开始往前送,这种贪心策略是最优的

为什么呢 ? ? ? , 如果从前开始送的话,那么当前点,只需要两个物资,但是你可以带三个

物资, 如果你去送后面的点,只会让答案增加

但是如果从后往前的话,那么你剩下来的,物资可以在回去的途中就送了,不会给继续

增加额外的答案

题目中又说明了,送完之后无需返回,当然我们做题的时候假定可以返回,这样子我

们方便计算答案,最后的时候减去那回去的距离即可

#include <iostream>
#include <vector>
#include <map>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
#define IOS  ios::sync_with_stdio(false);
#define CIT  cin.tie(0);

#define ll long long
#define pb push_back
#define endl '\n'
#define all(x) (x).begin(),x.end()

typedef pair<int,int> pii;
typedef vector<int> VI;
map<int,int> mp;

const int N  = 1e5+10;
int n,k;

void solve()
{
	VI A,B;
	
	cin>>n>>k;
	int maxn = 0 ;
	
	for(int i = 1;i<=n;i++){
		int x;cin>>x;
		if(x<0) B.pb(-x);
		else A.pb(x);
		x=abs(x);
		maxn = max(x,maxn);
	}	
	
	sort(all(A));
	sort(all(B));
	
	ll ans =  0 ;
	
	for(int i = A.size() - 1; i>= 0; i-=k){
		ans+= 1ll * A[i]*2;
	}
	
	for(int i = B.size()-1;i>=0; i-=k){
		ans+= 1ll* B[i]*2;
	}
	
	cout<<ans - maxn<<endl;
	
}
int main()
{
    int t;cin>>t;while(t -- )
    solve();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值