Acwing第46场周赛 1,2+AtCoder Regular Contest138 A

AtCoder Regular Contest138 对于我来说难度太大,我们只看A题

目录

Acwing第46场周赛

1.取石子

2.卡牌

AtCoder Regular Contest138 A

问题陈述

约束

输入

输出

示例输入 1 复制

示例输出 1 复制

示例输入 2 复制

示例输出 2 复制

示例输入 3 复制

示例输出 3 复制


Acwing第46场周赛

1.取石子

两个小朋友玩取石子游戏。

第一个小朋友面前有 n1n1 个石子,第二个小朋友面前有 n2n2 个石子。

两人轮流取自己面前的石子。

第一个小朋友先手,第二个小朋友后手。

第一个小朋友每轮次最多取 k1k1 个石子,最少取 11 个石子。

第二个小朋友每轮次最多取 k2k2 个石子,最少取 11 个石子。

率先取完自己面前石子的小朋友,视为失败

请问,两个小朋友都采取最优策略的情况下,谁会获胜

输入格式

一行,四个整数 n1,n2,k1,k2n1,n2,k1,k2。

输出格式

如果第一个小朋友获胜,则输出 First,如果第二个小朋友获胜,则输出 Second

数据范围

所有测试点满足 1≤n1,n2,k1,k2≤501≤n1,n2,k1,k2≤50。

输入样例1:

2 2 1 2

输出样例1:

Second

输入样例2:

2 1 1 1

输出样例2:

First

 分析

先取完就会输,那么最优方案就是取的越慢越好,每次只取 1次

思路:每次最少取1个的情况下 石子数多的人获胜
由于先手所以石子数相同时 第2个人获胜

 

#include<iostream>
using namespace std;
int main(){
	int n1,n2,k1,k2;
	cin>>n1>>n2>>k1>>k2;
	cout<<(n1<=n2?"Second":"First")<<endl;
	return 0;
}

2.卡牌

有 nn 张卡牌,编号 1∼n1∼n。

每张卡牌的正面和背面都各有一个数字。

第 ii 张卡牌的正面数字为 aiai,背面数字为 bibi。

初始时,所有卡牌都正面朝上,显示正面的数字。

现在,你可以将其中一些卡牌翻面,使其显示背面的数字,要求:

  1. 至少有 kk 张卡牌保持正面朝上。
  2. 所有卡牌显示的数字之和尽可能小。

输出所有卡牌显示的数字之和的最小可能值。

输入格式

第一行包含两个整数 n,kn,k。

第二行包含 nn 个整数 a1,a2,…,ana1,a2,…,an。

第三行包含 nn 个整数 b1,b2,…,bnb1,b2,…,bn。

输出格式

一个整数,表示所有卡牌显示的数字之和的最小可能值。

数据范围

前 66 个测试点满足 1≤n≤101≤n≤10。
所有测试点满足 1≤n≤2×1051≤n≤2×105,0≤k≤n0≤k≤n,1≤ai,bi≤1041≤ai,bi≤104。

输入样例1:

3 1
5 4 6
3 1 5

输出样例1:

10

输入样例2:

5 3
3 4 7 10 3
4 5 5 12 5

输出样例2:

25

 优先队列

#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
typedef pair<int,int> pii;
typedef pair<int,pii> pipii;
typedef pair<long long,int> pli;
const int N = 2e5+10;
ll res;
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n,k;
	cin>>n>>k;
	int a[N],b[N];
	for(int i = 0;i<n;i++) cin>>a[i];
	for(int i = 0;i<n;i++) cin>>b[i];
	priority_queue<int,vector<int>,greater<int> > q;
	for(int i = 0;i<n;i++){
		res+=a[i];
		q.push(b[i]-a[i]);
	}
	k = n - k;
	while(q.size()){
		if(!k) break;
		int t = q.top();
		q.pop();
		if(t>=0) break;
		res+=t;
		k--;
		if(!k) break;
	}
	cout<<res<<endl;
	return 0;
}

AtCoder Regular Contest138 A

A - 较大分数社论

 / 


时间限制: 3 秒 / 内存限制: 1024 MB

得分 : 积分400400

问题陈述

我们有一个长度的整数序列:。下面在这个问题上,让 的分数成为 的第一项之和。此外,让我们成为输入中给定的序列的分数。NNA=(A_1,A_2,\cdots,A_N)A=(A1​,A2​,⋯,AN​)AAKKAAssAA

您可以执行以下操作任意次数。

  • 选择 两个相邻的元素并交换它们。AA

你的目标是至少得分。确定目标是否可实现。如果是,请找到实现它所需的最小操作数。s+1s+1

约束

  • 2 \leq N \leq 4 \times 10^52≤N≤4×105
  • 1 \leq K \leq N-11≤KN−1
  • 1 \leq A_i \leq 10^91≤Ai​≤109
  • 输入中的所有值都是整数。

输入

输入从标准输入以下列格式提供:

NN KK
A_1A1​ A_2A2​ \cdots⋯ A_NAN

输出

如果目标无法实现,请打印 。如果可实现,请打印实现它所需的最小操作数。-1


示例输入 1 复制

复制
4 2
2 1 1 2

示例输出 1 复制

复制
2

我们有。以下操作序列使分数至少为 。s=2+1=3s=2+1=344

  • (2,1,1,2) \to ((2,1,1,2)→(交换和交换和A_3A3​A_4)\to (2,1,2,1) \to (A4​)→(2,1,2,1)→(A_2A2​A_3)\to (2,2,1,1)A3​)→(2,2,1,1)

该目标在一次操作中无法实现,因此所需的最小操作数为 。22


示例输入 2 复制

复制
3 1
3 2 1

示例输出 2 复制

复制
-1

示例输入 3 复制

复制
20 13
90699850 344821203 373822335 437633059 534203117 523743511 568996900 694866636 683864672 836230375 751240939 942020833 865334948 142779837 22252499 197049878 303376519 366683358 545670804 580980054

示例输出 3 复制

复制
13

 

 我想吐槽一句,这叫签到题???

 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD = 1000000007;
using P=pair<ll,ll>;
const ll inf = 1ll<<60;
int main() {
    ll n,k;
    cin >> n >> k;
    vector<P>a(n);
    for(ll i=0;i<n;i++){
        ll x;
        cin >> x;
        a[i]={x,-i};
    }
    sort(a.begin(),a.end());
    for(ll i=0;i<n;i++){
        a[i].second*=-1;
    }
    ll now=-inf;
    ll ans=inf;
    for(ll i=0;i<n;i++){
        if(a[i].second<k){
            now=max(now,a[i].second);
        }else{
            if(now!=-inf){
                ans=min(ans,a[i].second-now);
            }
        }
    }
    if(ans==inf){
        cout << -1 << endl;
    }else{
        cout << ans << endl;
    }
}

  • 21
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 23
    评论
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超级小何

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值