BZOJ 3108: [cqoi2013]圖的逆變換
Memory Limit: 128 MB
Description
給一個n結點m條邊的有向圖D,可以這樣構造圖E:給D的每條邊u->v,在E中建立一個點uv,然後對於D中的兩條邊u->v和v->w,在E中從uv向vw連一條有向邊。E中不含有其他點和邊。
輸入E,你的任務是判斷是否存在相應的D。注意,D可以有重邊和自環。
Input
第一行包含測試資料個數T(T<=10)。每組資料前兩行為D的邊數(即E的點數)m和E的邊數k(0<=m<=300)。以下k 行每行兩個整數x, y,表示E中有一條有向邊x->y。E中的點編號為0~m-1。
Output
對於每組資料輸出一行。如果存在,輸出Yes,否則輸出No。
Sample Input
4
2
1
0 1
5
0
4
3
0 1
2 1
2 3
3
9
0 1
0 2
1 2
1 0
2 0
2 1
0 0
1 1
2 2
Sample Output
Yes
Yes
No
Yes
題解:暴力搜尋+剪枝;
整理一下判斷條件:
1.這一行是否有重複的數
2.這一列是否有重複的數
3.這一個小九宮格中是否有重複的數
4.是否符合大於小於的條件
現在我分別用h[i][j] ,l[i][j] ,g[i][j] 來表示第i行,第i列,第i個小九宮格中數字j是否重複。還有一個大於小於號的問題後面再說,讓我們先來看一下讀入。
輸入格式: 一共15行,包含一個新數獨的例項。第奇數行包含左右方向的符號(<和>),第偶數行包含上下方向的符號(^和v)
說是奇數行包含左右方向的符號,偶數行包含上下方向的符號,其實如果你仔細的看一下題目或者樣例輸入的話,應該不難發現輸入格式的描述略有問題,有的行與輸入描述是相反的。。。(如果已經改過來了就當我沒說)
其實可以這樣看:輸入是有15行的,你可以把這15行分成3組,每組5行,這樣描述就對了,每一組的奇數行和偶數行按描述進行讀入即可。
讀入符號之後,先看這個符號屬於哪一個小九宮格(因為不同小九宮格的符號是不相關的),然後就要用到下面這個陣列了:
f[i][x][y]
它表示第i個小九宮格中第x個數和第y個數是否有大小關係。
讀入的時候如果是">"或者"v"就在相應的位置儲存1,如果是"<"或"^"就儲存2。
那麼這樣一來符號的問題就不是問題了,在選數的時候多加一個迴圈判斷一下這個數週圍的大小關係是否合法不就行了?
參考程式碼為:
#include<iostream> #include<bits/stdc++.h> using namespace std; int a[10][10],h[10][10],l[10][10],g[10][10],m,n,c,f[10][10][10]; void dfs(int x,int y) { if(x==9&&y==10) { for(int i=1;i<=9;++i) { for(int j=1;j<=9;++j) printf("%d ",a[i][j]); cout<<endl; } return; } if(y==10) x=x+1,y=1; for(int i=1;i<=9;++i) { bool bl=0; int g1=((x-1)/3)*3,g2=(y-1)/3,g3=g1+g2; if(g[g3][i]==1||h[x][i]==1||l[y][i]==1) continue; for(int j=1;j<=9;++j) { int ii=(x-1)%3*3+(y-1)%3+1; if(f[g3][ii][j]==1) { int xj=g3/3*3+(j-1)/3+1,yj=g3%3*3+(j-1)%3+1; if(a[xj][yj]!=0) if(i<a[xj][yj]) { bl=1; break; } } if(f[g3][ii][j]==2) { int xj=g3/3*3+(j-1)/3+1,yj=g3%3*3+(j-1)%3+1; if(a[xj][yj]!=0) if(i>a[xj][yj]) { bl=1; break; } } } if(bl==1) continue; g[g3][i]=1;h[x][i]=1;l[y][i]=1; a[x][y]=i; dfs(x,y+1); a[x][y]=0; g[g3][i]=0;h[x][i]=0;l[y][i]=0; } } int main() { int ci=0; char s; for(int i=1;i<=3;++i) { for(int k=1;k<=5;++k) { if(k%2==1) { for(int j=1;j<=6;++j) { int q1=(i-1)*3,q2=(j-1)/2,q3=q1+q2; cin>>s; if(s=='>') { int qq=(k-1)/2*3+(j-1)%2+1; f[q3][qq][qq+1]=1; f[q3][qq+1][qq]=2; } else { int qq=(k-1)/2*3+(j-1)%2+1; f[q3][qq][qq+1]=2; f[q3][qq+1][qq]=1; } } } else { for(int j=1;j<=9;++j) { int q1=(i-1)*3,q2=(j-1)/3,q3=q1+q2; cin>>s; if(s=='v') { int qq=(k-1)/2*3+(j-1)%3+1; f[q3][qq][qq+3]=1; f[q3][qq+3][qq]=2; } else { int qq=(k-1)/2*3+(j-1)%3+1; f[q3][qq][qq+3]=2; f[q3][qq+3][qq]=1; } } } } } dfs(1,1); return 0; }