Educational Codeforces Round 73 (Rated for Div. 2)

这场还是很有区分度的(逃

A

贪心,从小到大模拟合并的过程。

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;

inline void read(int &x) {
    int s=0;x=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    x*=s;
}

int main(){
	int T; cin>>T;
	while(T--){
		priority_queue<int, vector<int>, greater<int>> q;
		int n; cin>>n;
		rep(i,1,n){
			int t; cin>>t;
			q.push(t);
		}
		
		bool ok=false;
		while(q.size()){
			int t=q.top();
			if(t==2048){
				ok=true;
				break;
			}
			q.pop();
			if(!q.size()) break;
			int tt=q.top();
			if(t!=tt) continue;
			q.pop(), q.push(2*t);
		}
		puts(ok? "YES": "NO");
	}
    return 0;
}

B

间隔地二染色即可(像国际象棋盘一样)。注意到对于每一个骑士的攻击范围都是对手,因此贡献一定被最大化了。

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;

inline void read(int &x) {
    int s=0;x=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    x*=s;
}

int main(){
	int n; cin>>n;
	rep(i,1,n){
		rep(j,1,n) if(i+j&1) cout<<'W'; else cout<<'B';
		cout<<endl;
	} 
    return 0;
}

C

二分答案。

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;

inline void read(int &x) {
    int s=0;x=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    x*=s;
}

int a, b, c;

bool check(int v){
	if(v>min(a, b)) return false;
	int last=a+b-2*v+c;
	return last>=v;
}

int main(){
	int t; cin>>t;
	while(t--){
		cin>>a>>b>>c;
		
		int l=0, r=1e8;
		while(l<r){
			int mid=l+r+1>>1;
			if(check(mid)) l=mid;
			else r=mid-1;
		}
		cout<<l<<endl;
	}
    return 0;
}

D

贪心 + 状态机DP
注意多测不要大力 memset 不然会 T 飞。

注意到一个格子的高度最多只需要拔高 2 格。
\(f[i][op]\) 表示前 \(i\) 格合法而且将第 \(i\) 格拔高了 \(op\) 单位高度的最小花费数。\(op = 0, 1, 2\) 。转移方程为:

\[f[i][op] = min(f[i-1][pre])~~(a[i]+op\neq a[i-1]+pre) \]

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;

#define int long long 

inline void read(int &x) {
    int s=0;x=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    x*=s;
}

const int N=3e5+5;
int f[N][3];
int a[N], b[N];

signed main(){
	int T; read(T);
	while(T--){
		// memset(f, 0x3f, sizeof f);
		int n; read(n);
		rep(i,1,n) rep(j,0,2) f[i][j]=ll_INF;
		
		rep(i,1,n) read(a[i]), read(b[i]);
		
		f[1][0]=0, f[1][1]=b[1], f[1][2]=2*b[1];
		rep(i,2,n){
			rep(op,0,2){
				int &v=f[i][op];
				rep(pre,0,2)
					if(a[i]+op!=a[i-1]+pre) v=min(v, f[i-1][pre]);
				v+=op*b[i];
			}
		}
		
		int res=min(f[n][0], min(f[n][1], f[n][2]));
		cout<<res<<endl;
	}
    return 0;
}
posted @ 2021-07-01 17:36  HinanawiTenshi  阅读(39)  评论(0编辑  收藏  举报