Educational Codeforces Round 85 (Rated for Div. 2)
题外话
最近要多打cf ,十分容易上分的哈
A
A.题意
给你两个数值, 要求就是第一个要大于第二个, 且上一次的要小于这一次的
A.思路
按照题意模拟就行
A.代码
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define eps 1e-8
#define maxn 1000010
#define maxe 1000010
#define cl(x) memset(x,0,sizeof(x))
#define rep(i,a,b) for(i=a;i<=b;i++)
#define drep(i,a,b) for(i=a;i>=b;i--)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
#define pb push_back
#define de(x) cerr<<#x<<" = "<<x<<endl
#define __i __int128
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> pii;
//typedef pair<ll,ll> pll;
//
//ll read(ll x=0)
//{
// ll c, f(1);
// for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
// for(;isdigit(c);c=getchar())x=x*10+c-0x30;
// return f*x;
//}
const int N =100010;
ll n , k , m ;
void clear(unsigned char *pta, int size )
{
while(size>0)
{
*pta++ = 0;
size --;
}
}
ll ar[200010] , num =0 ;
ll br[200010],cr[200010];
struct node {
int x , y;
double num;
}p[100010];
double cmp(node a , node b){
return a.y*b.x>b.y*a.x;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin>>n;
while(n--){
cin >>m;
int pos =0 , num =0 ;int flag =1 ;
for(int i=0;i<m;i++){
int a,b; cin >>a >>b;
if(pos >a || num >b||b-num> a -pos)flag =0 ;
pos =a, num =b;
}
if(flag )cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
B
B.题意
给你一组数, 问你通过平分, 可以搞出来多少大于等于k的数
B.思路
直接sort 排序就,然后平分就行
B.代码
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define eps 1e-8
#define maxn 1000010
#define maxe 1000010
#define cl(x) memset(x,0,sizeof(x))
#define rep(i,a,b) for(i=a;i<=b;i++)
#define drep(i,a,b) for(i=a;i>=b;i--)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
#define pb push_back
#define de(x) cerr<<#x<<" = "<<x<<endl
#define __i __int128
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> pii;
//typedef pair<ll,ll> pll;
//
//ll read(ll x=0)
//{
// ll c, f(1);
// for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
// for(;isdigit(c);c=getchar())x=x*10+c-0x30;
// return f*x;
//}
const int N =100010;
ll n , k , m ;
void clear(unsigned char *pta, int size )
{
while(size>0)
{
*pta++ = 0;
size --;
}
}
ll ar[200010] , num =0 ;
ll br[200010],cr[200010];
struct node {
int x , y;
double num;
}p[100010];
int cmp (int a , int b ){
return a > b;}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin>>n;
while(n--){
ll sum =0 ;
cin >>m>>k;for(int i=0;i<m;i++)cin>>ar[i];
sort(ar,ar+m,cmp);ll num =0;
for(int i=0;i<m;i++){
if((num+ar[i])<k*(i+1))break;
num +=ar[i];
sum ++ ;
}cout<<sum <<endl;
}
return 0;
}
C
C.题意
给你n个怪物的血量和死亡后给后面怪物造成的伤害,(你每一次只能给怪物造成一点伤害),这n个怪物围绕成园,问你最少要多少发子弹能全杀死
C.思路
一开始,只知道应该是贪心, 但是如何贪心没有想出来。然后看了看题解,发现其实只需要确定第一个怪物(你要杀死的就行,后面其实都确定好了)
- 第一个怪物一定会给后面的怪物造成的伤害是最大的(这样你接下来打出的子弹会减少很多)
- 接下来就是补刀的过程, 哪个没死就给他一枪
- 具体做法就是, 记录一下每个怪物因为前面死亡后减少的血量是多少(存一下和), 然后找到一个最多的, 这个就是第一个你要杀死的(用前面的和减去这个差值),加上开枪的次数
- 时间复杂度是O(n)
C.代码
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define eps 1e-8
#define maxn 1000010
#define maxe 1000010
#define cl(x) memset(x,0,sizeof(x))
#define rep(i,a,b) for(i=a;i<=b;i++)
#define drep(i,a,b) for(i=a;i>=b;i--)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
#define pb push_back
#define de(x) cerr<<#x<<" = "<<x<<endl
#define __i __int128
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> pii;
//typedef pair<ll,ll> pll;
//
//ll read(ll x=0)
//{
// ll c, f(1);
// for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
// for(;isdigit(c);c=getchar())x=x*10+c-0x30;
// return f*x;
//}
const int N =300010 ;
ll n , k , m ;
void clear(unsigned char *pta, int size )
{
while(size>0)
{
*pta++ = 0;
size --;
}
}
ll ar[N] , num =0 ;
ll br[N],c[N];
struct node {
int x , y;
double num;
}p[100010];
int cmp (int a , int b ){
return a > b;}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >>n;
while(n--){
cin >>m;ll sum =0 ;
for(int i=0;i<m;i++){
cin >>ar[i]>>br[i];
}
for(int i=0;i<m;i++){
if(!i)c[i] = max(0ll ,ar[0] - br[m-1]);
else c[i] = max(0ll , ar[i] - br[i-1]);
sum +=c[i];
}
ll num =1e18 ;
for(int i=0 ;i<m;i++){
num = min(num, sum - c[i] + ar[i]);
}
cout<<num<<endl;
}
return 0;
}
D
D.题意
问你是否可以从1 开始走过所有边 (走过的边不能再走)
D.思路
- 一看这样应该要知道是个欧拉回路
我没看出来 - 然后看提示 发现当有三条边的时候 是这样的1 2 1 3 2 3 1
- 然后会发现 , 把每一个点作为开头的分为一组 例如 1 2 1 3 | 2 3 | 1
- 此时你会发现每个组是$ 2*(n-i) $
- 之后前缀和+ 二分即可
- 时间复杂度O(n)
D代码
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <queue>
#include <cstring>
#include <cassert>
#include<map>
#define cl(x) memset(x,0,sizeof(x))
#define rep(i,a,b) for(i=a;i<=b;i++)
#define drep(i,a,b) for(i=a;i>=b;i--)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
#define pb push_back
#define de(x) cerr<<#x<<" = "<<x<<endl
#define __i __int128
#define FOR(i, x, y) for (decay<decltype(y)>::type i = (x), _##i = (y); i < _##i; ++i)
#define FORD(i, x, y) for (decay<decltype(x)>::type i = (x), _##i = (y); i > _##i; --i)
#ifdef zerol
#define dbg(x...) do { cout << "\033[32;1m" << #x << " -> "; err(x); } while (0)
#else
#define dbg(...)
#endif
using namespace std;
//using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> pii;
void err() { cout << "\033[39;0m" << endl; }
template<template<typename...> class T, typename t, typename... A>
void err(T<t> a, A... x) { for (auto v: a) cout << v << ' '; err(x...); }
template<typename T, typename... A>
void err(T a, A... x) { cout << a << ' '; err(x...); }
//typedef pair<ll,ll> pll;
//
//ll read(ll x=0)
//{
// ll c, f(1);
// for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
// for(;isdigit(c);c=getchar())x=x*10+c-0x30;
// return f*x;
//}
const int N =100010;
ll n , k , m ;
void clear(unsigned char *pta, int size )
{
while(size>0)
{
*pta++ = 0;
size --;
}
}
ll MOD=1e9+7;
ll ar[N];
ll dfs(ll x){
if(x > ar[m-1])return 1;
auto a =lower_bound(ar+1,ar+m,x)-ar;
int b = x -ar[a-1];
if(b&1)return a;
else return b/2+a;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >>n;
while(n--){
ll l, r;
cin >>m>>l>>r;
ll i ;
rep(i,1 ,m+1)ar[i] = ar[i-1] +2*(m-i);
// for(int i=0;i<=m;i++)cout<<ar[i]<<" ";
rep(i,l , r)cout<<dfs(i)<<" ";
cout<<endl;
}
return 0;
}