1. 程式人生 > 實用技巧 >【USACO16OPEN】Bull in a China Shop(Bronze)

【USACO16OPEN】Bull in a China Shop(Bronze)

暴力列舉。不需要對資料進行預處理,直接平移。

兩層迴圈列舉碎片,四層迴圈列舉兩塊碎片平移的距離【如第一塊碎片左上角從(1,1)平移到(1+dx1,1+dy1)】,最後兩層迴圈判斷。

時間複雜度$O(N^{6}K^{2})$。

核心程式碼:

bool check(int p,int X,int Y)
{return X>0&&X<=n&&Y>0&&Y<=n&&(s[p][X][Y]=='#');}

for(int i=1;i<=k;++i)
	for(int j=i+1;j<=k;++j)
		for(int dx1=-n+1;dx1<=n-1;++dx1)
			for(int dy1=-n+1;dy1<=n-1;++dy1)
				for(int dx2=-n+1;dx2<=n-1;++dx2)
					for(int dy2=-n+1;dy2<=n-1;++dy2)
					{
						bool ok=1,c1,c2;
						for(int x=1;x<=n;++x)
							for(int y=1;y<=n;++y)
							{
								c1=check(i,x+dx1,y+dy1);
								c2=check(j,x+dx2,y+dy2);
								if (c1&&c2) ok=0;
								if ((s[0][x][y]=='#')!=(c1||c2)) ok=0;
							}
						if (ok) {printf("%d %d\n",i,j);return 0;}
					}

  

注意:用ok變數判斷是否合法,不要亂跳迴圈。不必刻意判斷$\texttt{#}$是否出界,只需判斷:

1.兩塊碎片的$\texttt{#}$是否重合;

2.碎片拼合後與原雕像是否一致。