Educational Codeforces Round 142 (Rated for Div. 2) 题解

再次被爆杀

Educational Codeforces Round 142 (Rated for Div. 2) 题解

Problem A

众所周知,一场比赛,Problem A 最难。

贪心策略,能用操作 2 就用操作 2,如果还剩下至少一个大于等于 1 的数,则对最小值和次小值用操作 1

Code
#include<bits/stdc++.h>
#define int long long
#define repe(i,l,r) for(int (i)=l;(i)<=r;(i)++)
#define rep(i,n) for(int (i)=1;(i)<=n;(i)++)
#define FOR(i,r,l) for(int (i)=r;(i)>=l;(i)--)
#define INF 0x3f3f3f
#define pii pair<int,int>
#define mpr make_pair
#define pb push_back
#define ALL(v) (v).begin(),(v).end()
#define rsort(v) sort(ALL(v),greater<int>())
#define lb(v,x) (int)(lower_bound(ALL(v),x)-v.begin())
#define ub(v,x) (int)(upper_bound(ALL(v),x)-v.begin())
#define uni(v) v.resize(unique(ALL(v))-v.begin())
using namespace std;
int read(){int sum=0,f=1;char c;c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){sum=(sum<<1)+(sum<<3)+(c-'0');c=getchar();}return sum*f;}
void out(int x){if(x<0){x=-x;putchar('-');}if(x>=10)out(x/10);putchar(x%10+'0');}
template <typename T>void die(T s){cout<<s<<endl;exit(0);}
int fast(int a,int b,int P){int res=1;if(P<=0){while(b){if(b&1)res=res*a;a=a*a;b>>=1;}}else{while(b){if(b&1)res=res*a%P;a=a*a%P;b>>=1;}}return res;}
template <typename T>void chkmax(T& a,T b){if(a<b)a=b;return;}
template <typename T>void chkmin(T& a,T b){if(a>b)a=b;return;}
int T=1,n;
int a[105],ans1,ans2;
void solve(){
	n=read();
	rep(i,n)a[i]=read();
	sort(a+1,a+n+1);
	ans1=0,ans2=n;
	rep(i,n){
		if(a[i]==1&&i!=n){
			ans2++;
			a[i]--,a[i+1]--;
		}
		if(!a[i])ans2--;
	}
	out(ans2);
	puts("");
	return;
}
signed main(){
	T=read();
	while(T--)solve();
	return 0;
}

Problem B

简单分讨题。

首先,我们可以发现,类型一肯定一开始就全用,操作二和操作三互补,也就是我们可以用一次操作二,再用操作三,直到当中有一个用完。剩下的就很清晰了。

Code
#include<bits/stdc++.h>
#define int long long
#define repe(i,l,r) for(int (i)=l;(i)<=r;(i)++)
#define rep(i,n) for(int (i)=1;(i)<=n;(i)++)
#define FOR(i,r,l) for(int (i)=r;(i)>=l;(i)--)
#define INF 0x3f3f3f
#define pii pair<int,int>
#define mpr make_pair
#define pb push_back
#define ALL(v) (v).begin(),(v).end()
#define rsort(v) sort(ALL(v),greater<int>())
#define lb(v,x) (int)(lower_bound(ALL(v),x)-v.begin())
#define ub(v,x) (int)(upper_bound(ALL(v),x)-v.begin())
#define uni(v) v.resize(unique(ALL(v))-v.begin())
using namespace std;
int read(){int sum=0,f=1;char c;c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){sum=(sum<<1)+(sum<<3)+(c-'0');c=getchar();}return sum*f;}
void out(int x){if(x<0){x=-x;putchar('-');}if(x>=10)out(x/10);putchar(x%10+'0');}
template <typename T>void die(T s){cout<<s<<endl;exit(0);}
int fast(int a,int b,int P){int res=1;if(P<=0){while(b){if(b&1)res=res*a;a=a*a;b>>=1;}}else{while(b){if(b&1)res=res*a%P;a=a*a%P;b>>=1;}}return res;}
template <typename T>void chkmax(T& a,T b){if(a<b)a=b;return;}
template <typename T>void chkmin(T& a,T b){if(a>b)a=b;return;}
int T,a,b,c,d;
int x,y;
void solve(){
	a=read(),b=read(),c=read(),d=read();
	x=y=0;
	x=a,y=a;
	int ans=a;
	if(x==0||y==0){
		puts("1");
		return;
	}
	ans+=min(b,c)*2;
	if(b>c){
		b-=c;
		if(y>=b)ans+=b,y-=b;
		else{
			cout<<ans+y+1<<endl;
			return;
		}
	}
	else{
		c-=b;
		if(x>=c)ans+=c,y-=c;
		else{
			cout<<ans+x+1<<endl;
			return;
		}
	}
	ans+=min(d,min(x,y)+1);
	cout<<ans<<endl;
	return;
}
signed main(){
	T=read();
	while(T--){
		solve();
	}
	return 0;
}

Problem C

我们先对于任意数据模拟一下,找出一个没有任何优化的方案。容易发现,假设数组大小为 n,则我们第 a 次进行的是操作必定是 (n2a+1,nn2+a) 进行,答案即为 n2

下面我们考虑优化,可以发现,如果对于第 a 次操作的二元组,如果它是包含第 a1 次操作的二元组,且二元组内顺序正常,那么他就是合法的,我们要找从第一次操作开始最长的连续合法序列,这个是可以优化的。

Code
#include<bits/stdc++.h>
#define int long long
#define repe(i,l,r) for(int (i)=l;(i)<=r;(i)++)
#define rep(i,n) for(int (i)=1;(i)<=n;(i)++)
#define FOR(i,r,l) for(int (i)=r;(i)>=l;(i)--)
#define INF 0x3f3f3f
#define pii pair<int,int>
#define mpr make_pair
#define pb push_back
#define ALL(v) (v).begin(),(v).end()
#define rsort(v) sort(ALL(v),greater<int>())
#define lb(v,x) (int)(lower_bound(ALL(v),x)-v.begin())
#define ub(v,x) (int)(upper_bound(ALL(v),x)-v.begin())
#define uni(v) v.resize(unique(ALL(v))-v.begin())
using namespace std;
int read(){int sum=0,f=1;char c;c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){sum=(sum<<1)+(sum<<3)+(c-'0');c=getchar();}return sum*f;}
void out(int x){if(x<0){x=-x;putchar('-');}if(x>=10)out(x/10);putchar(x%10+'0');}
template <typename T>void die(T s){cout<<s<<endl;exit(0);}
int fast(int a,int b,int P){int res=1;if(P<=0){while(b){if(b&1)res=res*a;a=a*a;b>>=1;}}else{while(b){if(b&1)res=res*a%P;a=a*a%P;b>>=1;}}return res;}
template <typename T>void chkmax(T& a,T b){if(a<b)a=b;return;}
template <typename T>void chkmin(T& a,T b){if(a>b)a=b;return;}
int T;
int n;
int a[200006],p[200005];
vector<int> L,R;
void solve(){
	n=read();
	rep(i,n)a[i]=read(),p[a[i]]=i;
	int res=0,ans=n-n/2;
	if(n&1){
//		res=1;
		FOR(i,n-n/2,2){
			if(p[i]>=p[i-1]&&p[n-i+1]<=p[n-i+2]&&p[i]<=p[n-i+1])res++;
			else{
				if(p[i]<=p[n-i+1])res++;
				goto chr;
			}
		}
		if(p[1]<=p[n]&&res==ans-1)res++;
		chr:;
		cout<<ans-res<<endl;
	}
	else{
		FOR(i,n/2,2){
			if(p[i]>=p[i-1]&&p[n-i+1]<=p[n-i+2]&&p[i]<=p[n-i+1])res++;
			else{
				if(p[i]<=p[n-i+1])res++;
				goto ktq;
			}
		}
		if(p[1]<=p[n]&&res==ans-1)res++;
		ktq:;
		cout<<ans-res<<endl;
	}
	return;
}
signed main(){
	T=read();
	while(T--)solve();
	return 0;
}

Problem D

我们做这道题时需要发现一个性质,即为当两个序列 p qpqk 时,那么对于序列 q 的前 k 个数就已经确定了。

Code
#include<bits/stdc++.h>
#define int long long
#define repe(i,l,r) for(int (i)=l;(i)<=r;(i)++)
#define rep(i,n) for(int (i)=1;(i)<=n;(i)++)
#define FOR(i,r,l) for(int (i)=r;(i)>=l;(i)--)
#define INF 0x3f3f3f
#define pii pair<int,int>
#define mpr make_pair
#define pb push_back
#define ALL(v) (v).begin(),(v).end()
#define rsort(v) sort(ALL(v),greater<int>())
#define lb(v,x) (int)(lower_bound(ALL(v),x)-v.begin())
#define ub(v,x) (int)(upper_bound(ALL(v),x)-v.begin())
#define uni(v) v.resize(unique(ALL(v))-v.begin())
using namespace std;
int read(){int sum=0,f=1;char c;c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){sum=(sum<<1)+(sum<<3)+(c-'0');c=getchar();}return sum*f;}
void out(int x){if(x<0){x=-x;putchar('-');}if(x>=10)out(x/10);putchar(x%10+'0');}
template <typename T>void die(T s){cout<<s<<endl;exit(0);}
int fast(int a,int b,int P){int res=1;if(P<=0){while(b){if(b&1)res=res*a;a=a*a;b>>=1;}}else{while(b){if(b&1)res=res*a%P;a=a*a%P;b>>=1;}}return res;}
template <typename T>void chkmax(T& a,T b){if(a<b)a=b;return;}
template <typename T>void chkmin(T& a,T b){if(a>b)a=b;return;}
int T;
int a[50005][15],n,m;
int hs[50005][15],p[50005][15];
unordered_map<int,bool> cnt[15];
const int base=1441,P=998244353;
int search(int id){
	int hss=0,res=0;
//	cout<<i<<endl;
	rep(i,m){
		hss=(hss*m+a[id][i]);
//		cout<<hss<<' ';
		if(cnt[i][hss]==1)res=i;
	}
	return res;
}
void solve(){
	n=read(),m=read();
	rep(i,m)cnt[i].clear();
	rep(i,n){
		rep(j,m){
			a[i][j]=read();
			p[i][a[i][j]]=j;
		}
	}
	rep(i,n){
		rep(j,m){
			hs[i][j]=(hs[i][j-1]*m+p[i][j]);
			cnt[j][hs[i][j]]=1;
		}
	}
	rep(i,n){
		cout<<search(i)<<' ';
	}
	puts("");
	return;
}
signed main(){
	T=read();
	while(T--)solve();
	return 0;
}
posted @   ktq_cpp  阅读(68)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示