Educational Codeforces Round 91 (Div. 2) 题解 (ABCD)

又水了4道题

A. Three Indices

感觉乱搞吧

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
#define mst(a,x) memset(a,x,sizeof(a))
#define fi first
#define se second
#define endl "\n"
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
//mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
const int N=200010; typedef long long ll; const int inf=~0u>>2; const ll INF=~0ull>>2; ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;} typedef double lf; const lf pi=acos(-1.0); lf readf(){lf x; if(scanf("%lf",&x)==-1)exit(0); return x;} typedef pair<ll,ll> pii;
const int mod=(0?1000000007:998244353); ll mul(ll a,ll b,ll m=mod){return a*b%m;} ll qpow(ll a,ll b,ll m=mod){ll ans=1; for(;b;a=mul(a,a,m),b>>=1)if(b&1)ans=mul(ans,a,m); return ans;}
int a[N],l[N],r[N];
void Solve(){
	int n=read();
	repeat(i,0,n)a[i]=read();
	l[0]=0;
	repeat(i,1,n)l[i]=a[l[i-1]]<a[i]?l[i-1]:i;
	r[n-1]=n-1;
	repeat_back(i,0,n-1)r[i]=a[r[i+1]]<a[i]?r[i+1]:i;
	repeat(i,1,n-1){
		if(a[l[i-1]]<a[i] && a[r[i+1]]<a[i]){
			cout<<"YES"<<endl;
			cout<<l[i-1]+1<<' '<<i+1<<' '<<r[i+1]+1<<endl;
			return;
		}
	}
	cout<<"NO"<<endl;
}
signed main(){
	int T=1; T=read();
	while(T--)Solve();
	return 0;
}

B. Universal Solution

完全可以只出一个招式,只要这个招式克制对方出的最多的那个招式

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
#define mst(a,x) memset(a,x,sizeof(a))
#define fi first
#define se second
#define endl "\n"
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
//mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
const int N=200010; typedef long long ll; const int inf=~0u>>2; const ll INF=~0ull>>2; ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;} typedef double lf; const lf pi=acos(-1.0); lf readf(){lf x; if(scanf("%lf",&x)==-1)exit(0); return x;} typedef pair<ll,ll> pii;
const int mod=(0?1000000007:998244353); ll mul(ll a,ll b,ll m=mod){return a*b%m;} ll qpow(ll a,ll b,ll m=mod){ll ans=1; for(;b;a=mul(a,a,m),b>>=1)if(b&1)ans=mul(ans,a,m); return ans;}
char s[N];
int cnt[256];
void Solve(){
	scanf("%s",s);
	mst(cnt,0);
	for(int i=0;s[i];i++)
		cnt[(int)s[i]]++;
	char c=max_element(cnt,cnt+256)-cnt;
	if(c=='R')c='P';
	else if(c=='P')c='S';
	else c='R';
	for(int i=0;s[i];i++)putchar(c);
	puts("");
}
signed main(){
	int T=1; T=read();
	while(T--)Solve();
	return 0;
}

C. Create The Teams

大意:尽可能地组队,要求每个队伍的人数乘以能力最低值大于等于x

贪心一下嘛,从能力大的开始选(因为这样需要人数是单调递减的)

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
#define mst(a,x) memset(a,x,sizeof(a))
#define fi first
#define se second
#define endl "\n"
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
//mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
const int N=200010; typedef long long ll; const int inf=~0u>>2; const ll INF=~0ull>>2; ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;} typedef double lf; const lf pi=acos(-1.0); lf readf(){lf x; if(scanf("%lf",&x)==-1)exit(0); return x;} typedef pair<ll,ll> pii;
const int mod=(0?1000000007:998244353); ll mul(ll a,ll b,ll m=mod){return a*b%m;} ll qpow(ll a,ll b,ll m=mod){ll ans=1; for(;b;a=mul(a,a,m),b>>=1)if(b&1)ans=mul(ans,a,m); return ans;}
int a[N];
void Solve(){
	int n=read(),x=read();
	repeat(i,0,n)a[i]=read(),a[i]=(x+a[i]-1)/a[i];
	sort(a,a+n);
	int pre=0,ans=0;
	repeat(i,0,n){
		if(a[i]<=i-pre+1){
			pre=i+1;
			ans++;
		}
	}
	cout<<ans<<endl;
}
signed main(){
	int T=1; T=read();
	while(T--)Solve();
	return 0;
}

D. Berserk And Fireball

大意:n个战士排成一排,分别有个武力值ai。你有两种法术,一个是火球(花费x个法力,消灭连续k个战士),一个是激怒(花费y个法力,选择相邻两个战士,武力值大的会消灭武力值小的)。求最后留下的战士排列成bi需要的最小法力花费(我的翻译水平咋样?

很显然,ai中会有一些战士需要留下来。考虑一个区间,区间内的所有战士需要被消灭,两端都要留下来,那么只要考虑3种可能的施法方法:

  1. 如果两端存在武力值大于区间内所有战士的战士,那么可以用这个牛逼战士干掉所有战士,花费 \(len\cdot y\)
  2. 如果使用火球比较划算,那么只要 \(len\ge k\) 就能先使用 \(len\% k\) 次激怒,然后使用 \(len/k\) 次火球,让使用火球次数最大化
  3. 如果使用激怒比较划算,那么用方案1当然最好。如果方案1不能用,那么只要 \(len\ge k\) 就能先使用 \(len-k\) 次激怒,然后使用 1 次火球,让使用激怒次数最大化
#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
#define mst(a,x) memset(a,x,sizeof(a))
#define fi first
#define se second
#define endl "\n"
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
//mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
const int N=200010; typedef long long ll; const int inf=~0u>>2; const ll INF=~0ull>>2; ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;} typedef double lf; const lf pi=acos(-1.0); lf readf(){lf x; if(scanf("%lf",&x)==-1)exit(0); return x;} typedef pair<ll,ll> pii;
const int mod=(0?1000000007:998244353); ll mul(ll a,ll b,ll m=mod){return a*b%m;} ll qpow(ll a,ll b,ll m=mod){ll ans=1; for(;b;a=mul(a,a,m),b>>=1)if(b&1)ans=mul(ans,a,m); return ans;}
#define int ll
int a[N],b[N],n,m,x,k,y,ans;
void work(int l,int r){
	if(l>r)return;
	int len=r-l+1;
	int res=INF;
	if(*max_element(a+l,a+r+1)<max(a[l-1],a[r+1])){
		res=min(res,len*y);
	}
	if(len>=k){
		res=min(res,x+(len-k)*y);
		res=min(res,len/k*x+(len%k)*y);
	}
	if(res==INF)cout<<-1<<endl,exit(0);
	ans+=res;
}
void Solve(){
	n=read(),m=read(),x=read(),k=read(),y=read();
	repeat(i,1,n+1)a[i]=read(); a[0]=a[n+1]=-1;
	repeat(i,1,m+1)b[i]=read(); b[m+1]=-1;
	int t=1,pre=1;
	repeat(i,1,n+1)
	if(a[i]==b[t])
		work(pre,i-1),pre=i+1,t++;
	work(pre,n);
	if(t!=m+1)cout<<-1<<endl,exit(0);
	cout<<ans<<endl;
}
signed main(){
	int T=1; //T=read();
	while(T--)Solve();
	return 0;
}
posted @ 2020-07-13 01:07  axiomofchoice  阅读(228)  评论(1编辑  收藏  举报