首页 > 其他分享 >Codeforces Round 980 (Div. 2)

Codeforces Round 980 (Div. 2)

时间:2024-10-21 16:16:31浏览次数:8  
标签:dist int res 980 Codeforces cin que Div include

A - Profitable Interest Rate

void solve()
{
	cin>>n>>m;
	if(n>=m)cout<<n<<'\n';
	else 
	{
		int c=m-n;
		if(c>=n)cout<<"0\n";
		else cout<<n-c<<'\n';
	}
	return ;
}

B - Buying Lemonade

其实就是判断排序后以每个点为最大值的时候所需要的柠檬水杯数是否大于给定的k

举个例子序列为1 2 3 4,k=5

假设1为最大值那么只能选1 1 1 1,此时选不满5个

假设2为最大值那么可以选1 2 2 2,此时可以选满5个,但是最坏情况下小于2号位置的所有位置会被多选择一次,所以输出k+(2-1)

假设L为最大值的时候可以选满k个则输出k+(L-1)

O(n)遍历即可(赛时写了个二分其实没必要)

int q[N];
bool check(int x)
{
	int res=0;
	_rep(i,1,x)
	{
		if(i!=x)res+=q[i];
		else res+=(n-i+1)*q[i];
	}
	return res>=m;
}
void solve()
{
	int yu=0,res=0;
	cin>>n>>m;
	_rep(i,1,n)cin>>q[i];
	sort(q+1,q+1+n);
	int l=1,r=n;
	while(l<r)
	{
		int mid=l+r>>1;
		check(mid)?r=mid:l=mid+1;
	}
	cout<<l-1+m<<'\n';
	return ;
}

C - Concatenation of Arrays

题意

给定n个长度为2的数组,现在要把这n个数组放到一排,问怎么放可以使这个长度为2*n的新数组逆序对最小

思路

假设单纯要使一个数组逆序对最小,直接sort即可

现在要使n个长度为2的小数组 拼在一起后的数组逆序对最少,猜测只需要改变一下sort的排序规则即可

一开始暴力判断 长度为2的小数组的前后顺序,判断两两之间的关系,假设a在前使得两两逆序对更少,那就把a排在前面,然后WA2了

发现这个排序具有传递性,也就是这个排序的‘=’可能是因为a==b,b==c那么默认a==c
所以要特判一下=的情况,例如下面这个样例

    输入
    1
    4
    7 8 1 10 3 4 5 6 

 {1 10}=={3 4},{1 10}=={5 6},{1 10}=={7 8},但是{3 4}<{5 6}<{7 8},所以相等状态下还要加一个大小关系的特判

错误输出:3 4 7 8 1 10 5 6 
加了if(x==y)return a.first+a.second<b.first+b.second;之后 输出(正确):3 4 1 10 5 6 7 8

D - Skipping


题意

简单来说,遇到这个题目

跳过的话下一次只能选择下标<=i的第一个没遇到过的题目并且或者a[i]分

提交的话下一次只能选择下标<=b[i]的第一个没遇到过的题目并且不得分

思路

模拟了一下样例很快就能发现,在i号点我有两个策略:

1:开始一直提交问题,把所有<=i的并且没遇到过的题目分数都加上

2:直接或者间接跳到下一个下标大于i的点,这样才能赚更多的分数

推到这一步之后,就可以想到,最后答案一定是遍历每个点,然后每个点都计算一下我跳过最少的分数到达这个点之后然后选择1策略能得到的分数,然后每次更新答案

所以这道题就是一个最短路问题,dist[i]维护的是从1号点到i号点所需要跳过(跳过之后就不能再选,就亏了)所亏的最少分数,建立所有i到b[i]的权值为a[i]的边以及所有i+1到i的权值为0的边,最后答案取res=max(res,\sum a[1,2,...i] -dist[i])

#include <map>
#include <set>
#include <queue>
#include <deque>
#include <cmath>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std;
#define fi first
#define se second
#define u1 (u<<1)
#define u2 (u<<1|1)
#define pb push_back
#define pp pop_back()
#define int long long
#define laile cout<<"laile"<<endl
#define lowbit(x) ((x)&(-x))
#define double long double
#define sf(x) scanf("%lld",&x)
#define sff(x,y) scanf("%lld %lld",&x,&y)
#define sd(x) scanf("%Lf",&x)
#define sdd(x,y) scanf("%Lf %Lf",&x,&y)
#define _for(i,n) for(int i=0;i<(n);++i)
#define _rep(i,a,b) for(int i=(a);i<=(b);++i)
#define _pre(i,a,b) for(int i=(a);i>=(b);--i)
#define all(x) (x).begin(), (x).end()
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
typedef unsigned long long ULL;
typedef pair<int,int>PII;
typedef pair<double,double>PDD;
const int N=1e6+10,INF=4e18;
int n,m;
int e[N],ne[N],w[N],idx,h[N];
int a[N],b[N];
int dist[N];
void add(int a,int b,int c)
{
	e[idx]=b;
	ne[idx]=h[a];
	w[idx]=c;
	h[a]=idx++;
}
bool st[N];
void dij()
{
	memset(dist,0x3f,(n+1)*8);
	memset(st,false,(n+1));
	priority_queue<PII,vector<PII>,greater<PII>>que;
	que.push({0,1});
	dist[1]=0;
	while(que.size())
	{
		auto t=que.top();
		que.pop();
		int u=t.se;
		if(st[u])continue;
		st[u]=true;
		for(int i=h[u];~i;i=ne[i])
		{
			int j=e[i],k=w[i];
			if(dist[j]>dist[u]+k)
			{
				dist[j]=dist[u]+k;
				que.push({dist[j],j});
			}
		}
	}
	return ;
}
int qian[N];
void solve()
{
	cin>>n;
	_rep(i,1,n)cin>>a[i],qian[i]=qian[i-1]+a[i];
	memset(h,-1,(n+1)*2*8);
	_rep(i,1,n)
	{
		cin>>b[i];
		add(i,b[i],a[i]);//i跳到b[i]要亏a[i]
		if(i!=n)add(i+1,i,0);
	}
	dij();
	int res=0;
	_rep(i,1,n)
	{
//		cout<<dist[i]<<" ";
		res=max(res,qian[i]-dist[i]);
	}
//	cout<<"\n";
	cout<<res<<'\n';
	return ;
}
signed main()
{
	IOS;
	int T=1;
    cin>>T;
	while(T--)
		solve();
	return 0;
}

标签:dist,int,res,980,Codeforces,cin,que,Div,include
From: https://blog.csdn.net/s1379659220/article/details/143114646

相关文章

  • 「题解」Codeforces Round 980 (Div. 2)
    before\(A\simD\)的题解A.ProfitableInterestRateProblemA.ProfitableInterestRateSol&Code数学题,有\(a-x\geqb-2x\),得\(x=b-a\)。特判\(a\geqb\)以及\(a<x\)的情况即可。#include<bits/stdc++.h>#defineM10001#defineN......
  • Educational Codeforces Round 165 (Rated for Div. 2) - VP记录
    A.TwoFriends一共只有两种情况:存在\(A\)的最好朋友是\(B\)且\(B\)的最好朋友是\(A\)的情况:此时只需邀请这两个人即可。不存在上述情况:设某个人\(A\)的最好朋友是\(B\),\(B\)的最好朋友是\(C\),这时邀请\(A,B,C\)三个人就可使\(A,B\)到场。根据上述两种情......
  • Codeforces Round 979 (Div. 2)
    CodeforcesRound979(Div.2)总结A首先第一位的贡献一定是\(0\),然后考虑接下来\(n-1\)位,我们可以把最大值和最小值放在第一位和第二位,这样贡献就是\((max-min)\times(n-1)\)。#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#includ......
  • 「题解」Codeforces Round 979 (Div. 2)
    before\(A\simD\)的题解A.AGiftFromOrangutanProblemA.AGiftFromOrangutanSol&Code\(c_i-b_i\)最大就是\(a\)的最大值减最小值。将\(a\)的最大值\(x\)和最小值\(y\)放到头两位即可得到答案\((x-y)(n-1)\)。#include<bits/stdc++.h>#defineM......
  • Codeforces Round 980 (Div. 2) C. Concatenation of Arrays
    题目:给定n个数组a1,a2,…,an。每个数组的长度都是2。因此,ai=[ai,1,ai,2]。你需要将这些数组连接成一个长度为2n的单一数组,以便使结果数组中的逆序数最小。注意,你不需要实际计算逆序的数量。更正式地说,你需要选择一个长度为n的排列p,使得数组b=[ap1,1,ap1,2,......
  • CF round 979 div2(D-E)
    D容易观察到需要连续一段区间。这不单点修改区间查询,然后我思维就开始往线段树飘了。。。并且我到这里就以为做完了开始想实现,实际上性质都没观察准确。。但是因为这是一个1500的题所以显然有不用线段树的解。题解是差分做的,确实差分也可以操作区间观察到“LR”一定是隔断点,那......
  • Codeforces Round 979 div2 个人题解(A~E)
    CodeforcesRound979div2个人题解(A~E)Dashboard-CodeforcesRound979(Div.2)-Codeforces火车头#define_CRT_SECURE_NO_WARNINGS1#include<algorithm>#include<array>#include<bitset>#include<cmath>#include<cstdio>#inc......
  • Codeforces Round 979 (Div. 2) C. A TRUE Battle
    题目链接:题目大意:Alice和Bob先后轮流向一串01字符串中加入or或and,前者想让结果为1后者想让结果为0,问Alice能不能赢。思路:对于相同的两个布尔值,or和and都不能改变它们,而对于Alice,他倾向于向01之间加入or,Bob则想加入and。一开始我想比较1和0的多少不就行了吗,但是不对,当你......
  • Codeforces Round 979 (Div. 2) B. Minimise Oneness
    题目链接:题目大意:构造长度为nnn的01字符串,使得全为零的子序列和至少有一个1的子序列的数量之差的绝对值最小。思路:很明显,所有子序列中不是全为0就是至少有一个1,所以算......
  • Codeforces Round 980 (Div. 2)
    糖丸了,什么沟史比赛A.ProfitableInterestRate初始有\(a\)个硬币,可以花费硬币开通盈利账户与非盈利账户开通盈利账户需要至少花费\(b\)个金币开通非盈利账户没有限制每在非盈利账户花费\(x\)元,盈利账户的限制\(b\)就减少\(2x\)元求最大的在盈利账户上的花......