CSP2025模拟赛7

用户头像 发布于 2025-08-22 137 次阅读 OI


S+CSP2025模拟赛7

A. 俄罗斯方块

暴力枚举。
代码:

#include<bits/stdc++.h>
using namespace std;

const int M=100;
char g[M][M];
bool v[M][M];
int n,m;
int c[5]={0};

struct B{
	char clr;
	int p[4][2];
	int num,mnx,mxx,mny,mxy;
};
bool ok(int x,int y){
	return x>=0&&x<n&&y>=0&&y<m;
}
void get(int x,int y,B &b){
	b.clr=g[x][y];
	b.num=0;
	b.mnx=b.mxx=x;
	b.mny=b.mxy=y;
	int sx[4],sy[4],t=0;
	sx[0]=x,sy[0]=y;
	v[x][y]=1;
	int dx[]={-1,1,0,0},dy[]={0,0,-1,1};
	while(t>=0&&b.num<4){
		int cx=sx[t],cy=sy[t--];
		b.p[b.num][0]=cx;
		b.p[b.num][1]=cy;
		b.num++;
		if(cx<b.mnx)b.mnx=cx;
		if(cx>b.mxx)b.mxx=cx;
		if(cy<b.mny)b.mny=cy;
		if(cy>b.mxy)b.mxy=cy;
		for(int i=0;i<4;i++){
			int nx=cx+dx[i],ny=cy+dy[i];
			if(ok(nx,ny)&&!v[nx][ny]&&g[nx][ny]==b.clr){
				v[nx][ny]=1;
				sx[++t]=nx;
				sy[t]=ny;
			}
		}
	}
}
void rel(B &b,int r[4][2]){
	for(int i=0;i<4;i++){
		r[i][0]=b.p[i][0]-b.mnx;
		r[i][1]=b.p[i][1]-b.mny;
	}
}

bool sq(int r[4][2]){
	bool f[4]={0};
	for(int i=0;i<4;i++){
		int x=r[i][0],y=r[i][1];
		if((x==0&&y==0)||(x==0&&y==1)||(x==1&&y==0)||(x==1&&y==1)){
			if(x==0&&y==0)f[0]=1;
			else if(x==0&&y==1)f[1]=1;
			else if(x==1&&y==0)f[2]=1;
			else if(x==1&&y==1)f[3]=1;
		}else return 0;
	}
	return f[0]&&f[1]&&f[2]&&f[3];
}

bool ln(int r[4][2],B &b){
	if(b.mxx-b.mnx==0&&b.mxy-b.mny==3){
		for(int i=0;i<4;i++)
			if(r[i][0]!=0||r[i][1]<0||r[i][1]>3)
				return 0;
		return 1;
	}else if(b.mxx-b.mnx==3&&b.mxy-b.mny==0){
		for(int i=0;i<4;i++)
			if(r[i][1]!=0||r[i][0]<0||r[i][0]>3)
				return 0;
		return 1;
	}
	return 0;
}

bool z(int r[4][2],B &b){
	if((b.mxx-b.mnx==1&&b.mxy-b.mny==2)||(b.mxx-b.mnx==2&&b.mxy-b.mny==1)){
		bool f1[4]={0},fm1=1;
		for(int i=0;i<4;i++){
			int x=r[i][0],y=r[i][1];
			if((x==0&&y==0)||(x==0&&y==1)||(x==1&&y==1)||(x==1&&y==2)){
				if(x==0&&y==0)f1[0]=1;
				else if(x==0&&y==1)f1[1]=1;
				else if(x==1&&y==1)f1[2]=1;
				else if(x==1&&y==2)f1[3]=1;
			}else fm1=0;
		}
		bool f2[4]={0},fm2=1;
		for(int i=0;i<4;i++){
			int x=r[i][0],y=r[i][1];
			if((x==0&&y==1)||(x==1&&y==0)||(x==1&&y==1)||(x==2&&y==0)){
				if(x==0&&y==1)f2[0]=1;
				else if(x==1&&y==0)f2[1]=1;
				else if(x==1&&y==1)f2[2]=1;
				else if(x==2&&y==0)f2[3]=1;
			}else fm2=0;
		}
		return (fm1&&f1[0]&&f1[1]&&f1[2]&&f1[3])||(fm2&&f2[0]&&f2[1]&&f2[2]&&f2[3]);
	}
	return 0;
}

bool rz(int r[4][2],B &b){
	if((b.mxx-b.mnx==1&&b.mxy-b.mny==2)||(b.mxx-b.mnx==2&&b.mxy-b.mny==1)){
		bool f1[4]={0},fm1=1;
		for(int i=0;i<4;i++){
			int x=r[i][0],y=r[i][1];
			if((x==0&&y==1)||(x==0&&y==2)||(x==1&&y==0)||(x==1&&y==1)){
				if(x==0&&y==1)f1[0]=1;
				else if(x==0&&y==2)f1[1]=1;
				else if(x==1&&y==0)f1[2]=1;
				else if(x==1&&y==1)f1[3]=1;
			}else fm1=0;
		}
		bool f2[4]={0},fm2=1;
		for(int i=0;i<4;i++){
			int x=r[i][0],y=r[i][1];
			if((x==0&&y==0)||(x==1&&y==0)||(x==1&&y==1)||(x==2&&y==1)){
				if(x==0&&y==0)f2[0]=1;
				else if(x==1&&y==0)f2[1]=1;
				else if(x==1&&y==1)f2[2]=1;
				else if(x==2&&y==1)f2[3]=1;
			}else fm2=0;
		}
		return (fm1&&f1[0]&&f1[1]&&f1[2]&&f1[3])||(fm2&&f2[0]&&f2[1]&&f2[2]&&f2[3]);
	}
	return 0;
}

bool t(int r[4][2],B &b){
	if((b.mxx-b.mnx==1&&b.mxy-b.mny==2)||(b.mxx-b.mnx==2&&b.mxy-b.mny==1)){
		bool f1[4]={0},fm1=1;
		for(int i=0;i<4;i++){
			int x=r[i][0],y=r[i][1];
			if((x==0&&y==1)||(x==1&&y==0)||(x==1&&y==1)||(x==1&&y==2)){
				if(x==0&&y==1)f1[0]=1;
				else if(x==1&&y==0)f1[1]=1;
				else if(x==1&&y==1)f1[2]=1;
				else if(x==1&&y==2)f1[3]=1;
			}else fm1=0;
		}
		bool f2[4]={0},fm2=1;
		for(int i=0;i<4;i++){
			int x=r[i][0],y=r[i][1];
			if((x==0&&y==0)||(x==1&&y==0)||(x==1&&y==1)||(x==2&&y==0)){
				if(x==0&&y==0)f2[0]=1;
				else if(x==1&&y==0)f2[1]=1;
				else if(x==1&&y==1)f2[2]=1;
				else if(x==2&&y==0)f2[3]=1;
			}else fm2=0;
		}
		bool f3[4]={0},fm3=1;
		for(int i=0;i<4;i++){
			int x=r[i][0],y=r[i][1];
			if((x==0&&y==0)||(x==0&&y==1)||(x==0&&y==2)||(x==1&&y==1)){
				if(x==0&&y==0)f3[0]=1;
				else if(x==0&&y==1)f3[1]=1;
				else if(x==0&&y==2)f3[2]=1;
				else if(x==1&&y==1)f3[3]=1;
			}else fm3=0;
		}
		bool f4[4]={0},fm4=1;
		for(int i=0;i<4;i++){
			int x=r[i][0],y=r[i][1];
			if((x==0&&y==1)||(x==1&&y==0)||(x==1&&y==1)||(x==2&&y==1)){
				if(x==0&&y==1)f4[0]=1;
				else if(x==1&&y==0)f4[1]=1;
				else if(x==1&&y==1)f4[2]=1;
				else if(x==2&&y==1)f4[3]=1;
			}else fm4=0;
		}
		return (fm1&&f1[0]&&f1[1]&&f1[2]&&f1[3])||(fm2&&f2[0]&&f2[1]&&f2[2]&&f2[3])||(fm3&&f3[0]&&f3[1]&&f3[2]&&f3[3])||(fm4&&f4[0]&&f4[1]&&f4[2]&&f4[3]);
	}
	return 0;
}

void chk(B &b){
	if(b.num!=4)return;
	int r[4][2];
	rel(b,r);
	if(sq(r))c[0]++;
	else if(ln(r,b))c[1]++;
	else if(rz(r,b))c[2]++;
	else if(z(r,b))c[3]++;
	else if(t(r,b))c[4]++;
}

int main(){
	freopen("tetris.in","r",stdin);
	freopen("tetris.out","w",stdout);
	cin>>n>>m;
	for(int i=0;i<n;i++)cin>>g[i];
	memset(v,0,sizeof(v));
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
			if(g[i][j]!='.'&&!v[i][j]){
				B b;
				get(i,j,b);
				chk(b);
			}
	for(int i=0;i<5;i++)cout<<c[i]<<endl;
	return 0;
}

B. 矩形染色

显而易见可以只统计一个象限,
可以贪心将所占纵向长度排序,
若当前横坐标比上一个大,说明有贡献。
代码:

#include<bits/stdc++.h>
using namespace std;
const int N=(1e7+5)/2;
struct node{
	int id,h;
};
int n;
long long ans;
node a[N];
bool cmp(node x,node y){
	return x.h>y.h;
}
signed main(){
	freopen("rect.in","r",stdin);
	freopen("rect.out","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++){
    	int x,y;
    	cin>>x>>y;
    	a[i]={x/2,y/2};
    }
    sort(a+1,a+1+n,cmp);
    int lst=0;
    for(int i=1;i<=n;i++) if(a[i].id>lst) ans+=1ll*(a[i].id-lst)*a[i].h,lst=a[i].id;
    cout<<ans*4ll;
    return 0;
}

C. 帝国重建

单调队列优化,
维护一个单调队列来高效找到最优分割点,
使得分割后的每一段(合并后的堆)高度非递减,
最终用总堆数减去最大保留段数得到最少合并次数。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e6+5;
int n,l,r;
int a[N],s[N],dp[N],q[N];
signed main(){
	freopen("empire.in","r",stdin);
	freopen("empire.out","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i],a[i]+=a[i-1];
    for(int i=1;i<=n;i++){
        while(l<r&&a[i]-a[q[l+1]]>=s[q[l+1]]) l++;
        dp[i]=dp[q[l]]+1,s[i]=a[i]-a[q[l]];
        while(l<=r&&s[q[r]]+a[q[r]]>a[i]+s[i]) r--;
        q[++r]=i;
    }
    cout<<n-dp[n];
    return 0;
}