The 1st Universal Cup Stage 5: Osijek, February 25-26, 2023 题解

G

Problem G. Gridlandia
Input file: standard input
Output file: standard output
Time limit: 1 second
Memory limit: 256 megabytes
给一个 n ∗ n n*n nn的矩阵,每个格子可以选取上下左右一条边(可以不选),所有选取的边不能共点。现在要求构造一个方案,选尽量多的边。

The continent of Gridlandia is a squares of side length n, divided into n2 square contries of side length. Each country has the resources to choose at most one of its four sides and build a ‘wall’ covering that entire side. However, since all the countries are at war, no two countries are willing to have their walls touch, even at the wall’s endpoints.
Find the maximum number of walls that can be built in Gridlandia, and construct a configuration where the maximum number of walls are built.
Input
The only line of input contains a single integer n (1 ≤ n ≤ 103) – the number of squares on each side of the grid.
Output
The output should consist of n lines.
Each line should contain n characters, each being blank (represented by ‘.’) or one of ‘ULDR’.
A dot represents a country with no walls, whereas each of the characters ‘ULDR’ represents a country that builds a wall on its ‘Up’, ‘Down’, ‘Left’, and ‘Right’ sides respectively.

#include<bits/stdc++.h> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
						For(j,m-1) cout<<a[i][j]<<' ';\
						cout<<a[i][m]<<endl; \
						} 
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
	return x*f;
} 
#define MAXN (1010)
char f[MAXN][MAXN];
int n;
bool inside(int i) {
	return 1<=i&&i<=n;
}
bool inside(int i,int j) {
	return inside(i)&inside(j);
}

bool ck(int i,int j ,int p) {
	if(!inside(i,j) || f[i][j]=='.') return 1;
	if(p==0) {
		return (f[i][j]=='D')||(f[i][j]=='R');
	}
	if(p==1) {
		return (f[i][j]=='D')||(f[i][j]=='L');
	}
	if(p==2) {
		return (f[i][j]=='U')||(f[i][j]=='R');
	}
	if(p==3) {
		return (f[i][j]=='U')||(f[i][j]=='L');
	}
}
bool ck(int i,int j,int p,int p2) {
	return ck(i,j,p)&&ck(i,j,p2);
}
int ct=0;
void dfs(int i,int j,int s=0) {
	int id=n*(i-1)+j;
	if(n*n-id+s<ct) return;
	if(i==n+1 && j==1) {
//		if(s==9) {
			For(i,n) {
				For(j,n) putchar(f[i][j]);cout<<endl;
			}
//		}
//		cout<<s<<endl;
		exit(0);
		gmax(ct,s)
		return ;
	}
	int ni=i,nj=j+1;
	if(j==n) ni=i+1,nj=1;
	
	f[i][j]='U';
	if(ck(i,j-1,1)&&ck(i-1,j,2,3)&&ck(i-1,j-1,3)&&ck(i-1,j+1,2)) {
		dfs(ni,nj,s+1);
	}	
	f[i][j]='L';
	if(ck(i-1,j,2)&&ck(i-1,j-1,3)&&ck(i,j-1,1,3) ) {
		dfs(ni,nj,s+1);
	}	
	f[i][j]='D';
	if(ck(i,j-1,3) ) {
		dfs(ni,nj,s+1);
	}	
	f[i][j]='R';
	if(ck(i-1,j,3) && ck(i-1,j+1,2)) {
		dfs(ni,nj,s+1);
	}	
	f[i][j]='.';
	dfs(ni,nj,s);
	
		
}
int main()
{
//	freopen("D.in","r",stdin);
//	freopen(".out","w",stdout);
	
	cin>>n;
	dfs(1,1);
//	cout<<ct;
	return 0;
}

I Julienne the Deck

给一个长度为n的排列 1 , ⋯   , n 1,\cdots,n 1,,n,每次操作可以选择 i ( 1 ≤ i < n ) i(1\le i \lt n) i(1i<n) $并同时翻转前i个数和后n-i个数,问最后可形成的排列数。

#include<bits/stdc++.h> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
						For(j,m-1) cout<<a[i][j]<<' ';\
						cout<<a[i][m]<<endl; \
						} 
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
	return x*f;
} 
#define MAXN (101010)
int a[MAXN];
map<vector<int> ,int > h;
int main()
{
//	freopen("D.in","r",stdin);
//	freopen(".out","w",stdout);
	
	ll n;cin>>n;
	if(n<=2) cout<<1<<endl;else
	cout<<n*2%998244353<<endl;
	return 0;
//	For(i,n) a[i]=i;
//	For(i,1e5) {
//		int p=rand()%(n-1)+2;
//		reverse(a+1,a+p);
//		reverse(a+p,a+n+1);
//		vi t;For(i,n) t.pb(a[i]);
//		h[t]=1;
//	} 
//	cout<<SI(h)<<endl;
	
	return 0;
}

J Knight’s Tour Redux

一个棋子每次可以从 ( x , y ) (x,y) (x,y)移动到 ( x ′ , y ′ ) (x',y') (x,y),当且仅当 ∣ x − x ′ ∣ |x-x'| xx ∣ y − y ′ ∣ |y-y'| yy中一个为1,一个为3.
现在你希望给出一条经过n个点的路径,要求所有横坐标恰为 1 1 1 n n n的排列,纵坐标也恰为 1 1 1 n n n的排列.

#include<bits/stdc++.h> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
						For(j,m-1) cout<<a[i][j]<<' ';\
						cout<<a[i][m]<<endl; \
						} 
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
	return x*f;
} 
#define MAXN (101010)
int a[MAXN]={},n;
int st2[MAXN];
int s[4]={-1,1,-3,3};
vi st;
bool inside(int x){return 1<=x && x<=n;}
map<vi ,vi > h,h_all;


void dfs(int x,int l) {
	if(l==0) {
		For(i,n) {
			a[i]=1;st2[l]=i;
			st[l]=i;
			dfs(i,1);
			a[i]=0;
		}
		return ;
	}
	if(l==n) {
//		cout<<"st:"<<endl;
		int t=0;
		For(i,n-1)if(abs(st[i])==1) t++;else t--;
		if(st2[0]==1 && st2[n-1]==n){
//			Rep(i,n) cout<<st2[i]<<" ";cout<<endl;
			vi tv,tv2;
			For(i,n-1) tv.pb(abs(st[i]));
			Rep(i,n) tv2.pb(st[i]);
			h[tv]=tv2;
//			For(i,n-1) cout<<abs(st[i])<<' ';cout<<endl<<endl;
		}
		{
			vi tv,tv2;
			For(i,n-1) tv.pb(abs(st[i]));
			Rep(i,n) tv2.pb(st[i]);
			h_all[tv]=tv2;
		}
		return ;
	}
	Rep(i,4) if(inside(x+s[i]) && !a[x+s[i]]) {
		a[x+s[i]]=1;
		st[l]=s[i];
		st2[l]=x+s[i];
		dfs(x+s[i],l+1);
		a[x+s[i]]=0;
	}
}
int dp[112345];
int main()
{
//	freopen("D.in","r",stdin);
//	freopen("j.out","w",stdout);
	cin>>n;
	if(n==1) {
		cout<<"POSSIBLE\n1 1\n";return 0;
	}
	if(n>=2 && n<=4) {
		puts("IMPOSSIBLE");return 0;
	}
	if(n<=20) {
		st.resize(n);
		dfs(0,0);
		for(auto a:h_all) {
			auto p=a.fi,p2=a.fi;
			Rep(i,n-1) p[i]=4-p[i];
			if(h_all.count(p)) {
				puts("POSSIBLE");
				auto r=h_all[p],w=h_all[p2];
				cout<<r[0]<<' '<<w[0]<<endl;
				int x=r[0],y=w[0];
				for(int i=1;i<SI(r);i++) {
					x+=r[i],y+=w[i];
					cout<<x<<' '<<y<<endl;					
				}
				return 0;
				cout<<"{";
				for(auto j:h[p]) cout<<j<<',';cout<<"0},{";
				for(auto j:h[p2]) cout<<j<<',';cout<<"0}";
				return 0;
			}
		}		
	}
	
	int st7[2][20]={{1,3,1,-3,1,3,1,0},{1,1,3,1,-3,1,3,0}};
	int st9[2][20]={{1,3,3,1,-3,-3,1,3,3,0},{1,1,1,3,-1,-1,3,1,1,0}};
	int st10[2][20]={{1,3,-1,-1,3,1,3,-1,-1,3,0},{1,1,3,3,-1,-3,-1,3,3,1,0}};
	int st11[2][20]={{1,3,3,3,-1,-3,-3,-1,3,3,3,0},{1,1,1,1,3,-1,-1,3,1,1,1,0}};
	
	For(i,n) dp[i]=-1;
	dp[0]=0;
	int bv[20]={0,6,8,9,10};
	For(i,n) {
		For(j,4) {
			int pr=i-bv[j];
			if(pr>=0 && dp[pr]!=-1) {
				dp[i]=pr;
			}
		}
	}
//	For(i,n) cout<<dp[i]<<" ";cout<<endl; 
	puts("POSSIBLE");
	int x=1,y=1;
	cout<<x<<' '<<y<<endl;
	n--;
	
	while(n) {
		int delta=n-dp[n];
		if(delta==6) {
			For(i,6) {
				x+=st7[0][i];
				y+=st7[1][i];
				cout<<x<<" "<<y<<endl;
			}
		}
		if(delta==8) {
			For(i,8) {
				x+=st9[0][i];
				y+=st9[1][i];
				cout<<x<<" "<<y<<endl;
			}
		}
		if(delta==9) {
			For(i,9) {
				x+=st10[0][i];
				y+=st10[1][i];
				cout<<x<<" "<<y<<endl;
			}
		}
		if(delta==10) {
			For(i,10) {
				x+=st11[0][i];
				y+=st11[1][i];
				cout<<x<<" "<<y<<endl;
			}
		}
		
		
		
		n=dp[n];
	}
	
	
	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值