1. 程式人生 > >[ZJOI2007] 小Q的矩陣遊戲【解題報告】

[ZJOI2007] 小Q的矩陣遊戲【解題報告】

i++ 想要 文件 lose () 決定 tdi 匹配 amp

戳我

660. [ZJOI2007] 小Q的矩陣遊戲

★★☆ 輸入文件:qmatrix.in 輸出文件:qmatrix.out 簡單對比
時間限制:1 s 內存限制:128 MB

【問題描述】 小Q是一個非常聰明的孩子,除了國際象棋,他還很喜歡玩一個電腦益智遊戲——矩陣遊戲。矩陣遊戲在一個N*N黑白方陣進行(如同國際象棋一般,只是顏色是隨意的)。每次可以對該矩陣進行兩種操作: l 行交換操作:選擇矩陣的任意兩行,交換這兩行(即交換對應格子的顏色) l 列交換操作:選擇矩陣的任意兩列,交換這兩列(即交換對應格子的顏色) 遊戲的目標,即通過若幹次操作,使得方陣的主對角線(左上角到右下角的連線)上的格子均為黑色。 對於某些關卡,小Q百思不得其解,以致他開始懷疑這些關卡是不是根本就是無解的!!於是小Q決定寫一個程序來判斷這些關卡是否有解。 【輸入文件】
輸入文件qmatrix.in第一行包含一個整數T,表示數據的組數。 接下來包含T組數據,每組數據第一行為一個整數N,表示方陣的大小;接下來N行為一個N*N的01矩陣(0表示白色,1表示黑色)。 【輸出文件】 輸出文件應包含T行。對於每一組數據,如果該關卡有解,輸出一行Yes;否則輸出一行No。 【樣例輸入】 2 2 0 0 0 1 3 0 0 1 0 1 0 1 0 0 【樣例輸出】 No Yes 【數據規模】 對於20%的數據,N≤ 7 對於50%的數據,N≤ 50

對於100%的數據,N≤ 200

我們可以發現,無論如何換,每個黑格子的相對位置總不會發生變化,即原來橫坐標不同的交換後也不會相同,縱坐標同理,而如果想要讓他們分布在對角線上,那麽要求存在n個橫縱坐標互不相同的黑點,那麽問題就變成了,在原來的若幹黑點中選出n個使得他們的橫縱坐標都不相同。其實就是每一個橫坐標匹配一個縱坐標,匈牙利算法即可。

代碼

技術分享
 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 int T,a[205][205],n,ans,result[205],vis[205];
 5 bool dfs(int x){
 6     for(int i=1;i<=n;i++){
 7         if(!a[x][i])continue;
 8         if(vis[i])continue;
 9         vis[i]=1;
10         if(!result[i]||dfs(result[i])){
11 result[i]=x; 12 return 1; 13 } 14 } 15 return 0; 16 } 17 int main() 18 { 19 freopen("qmatrix.in","r",stdin); 20 freopen("qmatrix.out","w",stdout); 21 scanf("%d",&T); 22 while(T--){ 23 scanf("%d",&n); 24 ans=0; 25 memset(result,0,sizeof(result)); 26 memset(a,0,sizeof(a)); 27 for(int i=1;i<=n;i++){ 28 for(int j=1;j<=n;j++){ 29 int x; 30 scanf("%d",&x); 31 if(x)a[i][j]=1; 32 } 33 } 34 for(int i=1;i<=n;i++){ 35 memset(vis,0,sizeof(vis)); 36 if(dfs(i))ans++; 37 } 38 if(ans==n)printf("Yes\n"); 39 else printf("No\n"); 40 } 41 return 0; 42 }
View Code

[ZJOI2007] 小Q的矩陣遊戲【解題報告】