2021牛客暑期多校训练营2 部分题解

C

签到题,看看最多加多少条边这个图还是树。

int main(){
	int a, b; cin>>a>>b;
	int res=a*b;
	if(res&1) puts("NO");
	else puts("YES");
	
    return 0;
}

D

签到题
模拟

int main(){
	int T; cin>>T;
	while(T--){
		int a, b, c, d; cin>>a>>b>>c>>d;
		
		if(a>b) swap(a, b);
		if(c>d) swap(c, d);
		
		bool ok=false;
		
		if(a==2 && b==8 && (c!=2 || d!=8)) puts("first"), ok=true;
		else if(a==b && c!=d && (c!=2 || d!=8)) puts("first"), ok=true;
		else if(a==b && c==d && a>c) puts("first"), ok=true;
		else if(a!=b && c!=d && (a+b)%10>(c+d)%10 && (c!=2 || d!=8)) puts("first"), ok=true;
		else if(a!=b && c!=d && (a+b)%10==(c+d)%10 && b>d && (c!=2 || d!=8)) puts("first"), ok=true;
		
		if(ok) continue;
		else{
			swap(a, c), swap(b, d);
			
			if(a==2 && b==8 && (c!=2 || d!=8)) puts("second"), ok=true;
			else if(a==b && c!=d && (c!=2 || d!=8)) puts("second"), ok=true;
			else if(a==b && c==d && a>c) puts("second"), ok=true;
			else if(a!=b && c!=d && (a+b)%10>(c+d)%10 && (c!=2 || d!=8)) puts("second"), ok=true;
			else if(a!=b && c!=d && (a+b)%10==(c+d)%10 && b>d && (c!=2 || d!=8)) puts("second"), ok=true;
			
			if(ok) continue; 
		}
		
		if(!ok) puts("tie");
	}	
    return 0;
}

I

四维 dfs
折磨题

本质和二维 dfs + 记录方案一样。

#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 all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;

#define x first
#define y second

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=25;

char buf[N][N], buff[N][N];
char ans[N][N], anss[N][N];
bool g[N][N], gg[N][N];
int dis[N][N][N][N];



struct Node{
	int a, b, c, d;
};

int tt=-1, hh=0;
Node q[N*N*N*N];

Node pre[N][N][N][N];

int dx[]={1, 0, 0, -1}, dy[]={0, -1, 1, 0}; // determination of the first pg.

int cnt[N][N][N][N];

int main(){
	const int n=20;
	rep(i,1,20){
		char ch; 
		rep(j,1,20){
			cin>>ch;
			buf[i][j]=ch;
			g[i][j]= ch=='.';
		}
		
		rep(j,1,20){
			cin>>ch;
			buff[i][j]=ch;
			gg[i][j]= ch=='.';
		}
	}
	
	int sx=20, sy=20, tx=1, ty=20;
	int sxx=20, syy=1, txx=1, tyy=1;
	
	q[++tt]={sx, sy, sxx, syy};
	
	memset(dis, 0x3f, sizeof dis);
	dis[sx][sy][sxx][syy]=0;
	
	while(tt>=hh){
		auto hd=q[hh++];
		int a=hd.a, b=hd.b, c=hd.c, d=hd.d;
		
		rep(i,0,3){
			int kx=a+dx[i], ky=b+dy[i];
			int kxx=c+dx[i], kyy=d-dy[i];
		
			if(kx<=0 || kx>n || ky<=0 || ky>n || !g[kx][ky]) kx=a, ky=b;
			if(kxx<=0 || kxx>n || kyy<=0 || kyy>n || !gg[kxx][kyy]) kxx=c, kyy=d;

			if(dis[kx][ky][kxx][kyy]>dis[a][b][c][d]+1){
				q[++tt]={kx, ky, kxx, kyy};
				dis[kx][ky][kxx][kyy]=dis[a][b][c][d]+1;
				pre[kx][ky][kxx][kyy]={a, b, c, d};
			}
			
			if(kx==tx && ky==ty && kxx==txx && kyy==tyy) break;
		}
	}
	
	cout<<dis[tx][ty][txx][tyy]<<endl;
	
	int cx=tx, cy=ty, cxx=txx, cyy=tyy; // current position
	
	buf[cx][cy]='A';
	buff[cxx][cyy]='A';
	
	vector<char> res;
	
	while(!(cx==sx && cy==sy && cxx==sxx && cyy==syy)){
		int px=pre[cx][cy][cxx][cyy].a, py=pre[cx][cy][cxx][cyy].b;
		int pxx=pre[cx][cy][cxx][cyy].c, pyy=pre[cx][cy][cxx][cyy].d;
		
		// judge direction:
		if(px==cx && py==cy){
			if(pxx==cxx+1) res.pb('U');
			else if(pxx==cxx-1) res.pb('D');
			else if(pyy==cyy+1) res.pb('R');
			else res.pb('L');
		}
		else{
			if(px==cx+1) res.pb('U');
			else if(px==cx-1) res.pb('D');
			else if(py==cy+1) res.pb('L');
			else res.pb('R');
		}
		
		cx=px, cy=py;
		cxx=pxx, cyy=pyy;
		
		buf[cx][cy]='A';
		buff[cxx][cyy]='A';
	}
	
	for(int i=res.size()-1; ~i; i--) cout<<res[i];
	cout<<endl;
	
	rep(i,1,20){
		rep(j,1,20) cout<<buf[i][j];
		cout<<' ';
		rep(j,1,20) cout<<buff[i][j];
		cout<<endl;
	}

    return 0;
}

K

单调栈的性质、构造。

sz[p] 表示位置 \(p\) 单调栈的大小,我们先将各个位置单调栈的大小存入 sz[] 中。

然后顺着扫一遍,如果对大小没有规定我们就模拟填数(大小加一)。如果发现规定的位置 \(p\) 的大小比前一个 \(+1\) 还大,那就不存在方案。

如果存在方案,我们开始构造。

逆序扫一遍,模拟逆过程即可,见代码。

#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 all(x) (x).begin(), (x).end()
#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;
}

const int N=1e6+5;

int n, k;

int sz[N];
int stk[N], top, cur;
int res[N];

int main(){
	read(n), read(k);
	rep(i,1,k){
		int p, x; read(p), read(x);
		sz[p]=x;
	}
	
	rep(i,1,n){
		if(!sz[i]) sz[i]=sz[i-1]+1;
		else if(sz[i]>sz[i-1]+1){
			puts("-1");
			return 0;
		}
	}
	
	dwn(i,n,1){
		while(top<sz[i]) stk[++top]=++cur;
		res[i]=stk[top--];
	}
	
	rep(i,1,n) cout<<res[i]<<' ';
	
    return 0;
}
posted @ 2021-07-23 22:03  HinanawiTenshi  阅读(50)  评论(0编辑  收藏  举报