[CSP-S模擬測試]:線性代數(模擬)

題目傳送門(內部題113)


輸入格式

  第一行一個正整數$n$。
  接下來$n$行,每行$n$個整數,描述$C$矩陣。保證輸入的是一個林先森矩陣。
html


輸出格式

  若不可能實現,則輸出一行$Impossible$;不然,輸出一行一個僅包含$\{U,D,L,R\}$的字符串,表示一個$typ$參數的序列。你的序列長度不能超過$10^6$。若不須要進行任何操做,請將該序列留空。c++


樣例

樣例輸入1:測試

2
1 2
3 0
spa

樣例輸出1:htm

Impossibleblog

樣例輸入2:字符串

3
3 2 5
4 1 8
6 7 0
get

樣例輸出2:it

UULDLUclass


數據範圍與提示

  本題採用子任務評分。僅當你經過一個子任務下全部測試點時,你才能得到該子任務的分數。
  對於全部數據,$1\leqslant n\leqslant 50$。
  $1.$($30$分)$n\leqslant 3$。
  $2.$($30$分)$n\leqslant 10$。
  $3.$($40$分)沒有特殊限制。


題解

其實就是一個大模擬。

咱們考慮從小到大填,也就是先填好右下角,每一行從右到左填,從下到上依次填好每一行,直到最後兩行無論。

先說怎麼填好每一行。

首先,先填好每一行$3\sim n$的每個數,方法很簡單,再也不贅述。

$1,2$位置須要一塊兒填,具體方法咱們能夠先想辦法將其變成以下圖所示的狀況$\downarrow$

上圖中,黑色爲已經填好的塊和邊界,橙色爲準備填的兩個塊,這樣咱們只須要將$0$向左再向上移動便可移動成下圖的狀態$\downarrow$

剩餘$1,2$兩行沒有填好時只須要按上面填每行的$1,2$的方法填補便可。

最後剩下左上角一個$2\times 2$的方格時判斷便可。

時間複雜度:$\Theta(n^3)$。

指望得分:$100$分。

實際得分:$100$分。


代碼時刻

#include<bits/stdc++.h>
using namespace std;
int n;
int Map[55][55],sec[55][55];
bool vis[55][55];
pair<int,int> pos[10000];
int top;
char ans[10000010];
int dis(int x,int y,int x2,int y2){return abs(x-x2)+abs(y-y2);}
void U()
{
	swap(Map[pos[0].first][pos[0].second],Map[pos[0].first-1][pos[0].second]);
	swap(pos[0],pos[Map[pos[0].first][pos[0].second]]);ans[++top]='U';
	if(top>1e6){puts("Impossible");exit(0);}
}
void D()
{
	swap(Map[pos[0].first][pos[0].second],Map[pos[0].first+1][pos[0].second]);
	swap(pos[0],pos[Map[pos[0].first][pos[0].second]]);ans[++top]='D';
	if(top>1e6){puts("Impossible");exit(0);}
}
void L()
{
	swap(Map[pos[0].first][pos[0].second],Map[pos[0].first][pos[0].second-1]);
	swap(pos[0],pos[Map[pos[0].first][pos[0].second]]);ans[++top]='L';
	if(top>1e6){puts("Impossible");exit(0);}
}
void R()
{
	swap(Map[pos[0].first][pos[0].second],Map[pos[0].first][pos[0].second+1]);
	swap(pos[0],pos[Map[pos[0].first][pos[0].second]]);ans[++top]='R';
	if(top>1e6){puts("Impossible");exit(0);}
}
int judge(int x,int y)
{
	if(pos[0]==make_pair(x,y+1))return 1;
	if(pos[0]==make_pair(x,y-1))return 2;
	if(pos[0]==make_pair(x-1,y))return 3;
	if(pos[0]==make_pair(x+1,y))return 4;
	return 0;
}
void change(int x,int y)
{
	while(1)
	{
		if(judge(x,y))break;
		int flag=0;
		if(pos[0].first-1==x&&pos[0].second==y)goto nxt1;
		if(pos[0].first>1&&dis(x,y,pos[0].first,pos[0].second)>dis(x,y,pos[0].first-1,pos[0].second)&&!vis[pos[0].first-1][pos[0].second]){U();flag=1;}
		nxt1:;
		if(pos[0].first+1==x&&pos[0].second==y)goto nxt2;
		if(pos[0].first<n&&dis(x,y,pos[0].first,pos[0].second)>dis(x,y,pos[0].first+1,pos[0].second)&&!vis[pos[0].first+1][pos[0].second]){D();flag=1;}
		nxt2:;
		if(pos[0].first==x&&pos[0].second-1==y)goto nxt3;
		if(pos[0].second>1&&dis(x,y,pos[0].first,pos[0].second)>dis(x,y,pos[0].first,pos[0].second-1)&&!vis[pos[0].first][pos[0].second-1]){L();flag=1;}
		nxt3:;
		if(pos[0].first==x&&pos[0].second+1==y)goto nxt4;
		if(pos[0].second<n&&dis(x,y,pos[0].first,pos[0].second)>dis(x,y,pos[0].first,pos[0].second+1)&&!vis[pos[0].first][pos[0].second+1]){R();flag=1;}
		nxt4:;
		if(!flag)break;
	}
}
void move(int k,int x,int y)
{
	int opt=judge(x,y);
	switch(k)
	{
		case 1:
			if(opt==1){U();L();D();}
			if(opt==2){U();R();D();}
			if(opt==3)D();
			if(opt==4)
			{
				if(y>1){L();U();U();R();D();}
				else{R();U();U();L();D();}
			}
		break;
		case 2:
			if(opt==1)
			{
				if(vis[x+1][y+1]){U();L();D();D();R();U();L();U();R();D();D();L();U();}
				else{D();L();U();}
			}
			if(opt==2){D();R();U();}
			if(opt==3)
			{
				if(y<n){R();D();}
				else{L();D();D();R();U();}
			}
			if(opt==4)U();
		break;
		case 3:
			if(opt==1){U();L();L();D();R();}
			if(opt==2)R();
			if(opt==3){L();D();R();}
			if(opt==4){L();U();R();}
		break;
		case 4:
			if(opt==1)L();
			if(opt==2)
			{
				if(x>1){U();R();R();D();L();}
				else
				{
					if(vis[x+1][y+1]){R();D();R();U();L();D();R();U();L();L();D();R();R();U();L();}
					else{D();R();R();U();L();}
				}
			}
			if(opt==3){R();D();L();}
			if(opt==4)
			{
				if(vis[x+1][y+1]){L();U();}
				else{R();U();L();}
			}
		break;
	}
}
void move(int x,int y)
{
	int res=sec[x][y];
	while(pos[res]!=make_pair(x,y))
	{
		bool flag=0;
		if(pos[res].first>1&&dis(x,y,pos[res].first,pos[res].second)>dis(x,y,pos[res].first-1,pos[res].second)&&!vis[pos[res].first-1][pos[res].second])
		{change(pos[res].first,pos[res].second);move(1,pos[res].first,pos[res].second);flag=1;}
		if(pos[res].first<n&&dis(x,y,pos[res].first,pos[res].second)>dis(x,y,pos[res].first+1,pos[res].second)&&!vis[pos[res].first+1][pos[res].second])
		{change(pos[res].first,pos[res].second);move(2,pos[res].first,pos[res].second);flag=1;}
		if(pos[res].second>1&&dis(x,y,pos[res].first,pos[res].second)>dis(x,y,pos[res].first,pos[res].second-1)&&!vis[pos[res].first][pos[res].second-1])
		{change(pos[res].first,pos[res].second);move(3,pos[res].first,pos[res].second);flag=1;}
		if(pos[res].second<n&&dis(x,y,pos[res].first,pos[res].second)>dis(x,y,pos[res].first,pos[res].second+1)&&!vis[pos[res].first][pos[res].second+1])
		{change(pos[res].first,pos[res].second);move(4,pos[res].first,pos[res].second);flag=1;}
		if(!flag)break;
	}
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
		{
			scanf("%d",&Map[i][j]);sec[i][j]=(i-1)*n+j-1;
			pos[Map[i][j]]=make_pair(i,j);
		}
	for(int i=n;i>2;i--)
		for(int j=n;j;j--)
		{
			move(i,j);
			vis[i][j]=1;
		}
	for(int j=n;j>1;j--)
	{
		move(2,j);vis[2][j]=1;
		move(1,j);vis[1][j]=1;
	}
	if(pos[0]!=make_pair(1,1)){swap(Map[1][1],Map[2][1]);ans[++top]='U';}
	printf("%s",ans+1);
	return 0;
} 

rp++

相關文章
相關標籤/搜索