【問題描述】
小 b 最近迷上了華容道,可是他總是要花很長的時間才能完成一次。於是,他想到用程式設計來完成華容道:給定一種局面, 華容道是否根本就無法完成,如果能完成, 最少需要多少時間。
小 b 玩的華容道與經典的華容道遊戲略有不同,遊戲規則是這樣的:
在乙個 n*m 棋盤上有 n*m 個格仔,其中有且只有乙個格仔是空白的,其餘 n*m-1個格仔上每個格仔上有乙個棋子,每個棋子的大小都是 1*1 的;
有些棋子是固定的,有些棋子則是可以移動的;
任何與空白的格仔相鄰(有公共的邊)的格仔上的棋子都可以移動到空白格仔上。
遊戲的目的是把某個指定位置可以活動的棋子移動到目標位置。
給定乙個棋盤,遊戲可以玩 q 次,當然,每次棋盤上固定的格仔是不會變的, 但是棋盤上空白的格仔的初始位置、 指定的可移動的棋子的初始位置和目標位置卻可能不同。第 i 次
玩的時候, 空白的格仔在第 exi 行第 eyi 列,指定的可移動棋子的初始位置為第 sxi 行第 syi列,目標位置為第 txi 行第 tyi 列。
假設小 b 每秒鐘能進行一次移動棋子的操作,而其他操作的時間都可以忽略不計。請你告訴小 b 每一次遊戲所需要的最少時間,或者告訴他不可能完成遊戲。
輸入格式:
輸入檔案為 puzzle.in。
第一行有 3 個整數,每兩個整數之間用乙個空格隔開,依次表示 n、m 和 q;
接下來的 n 行描述乙個 n*m 的棋盤,每行有 m 個整數,每兩個整數之間用乙個空格隔開,每個整數描述棋盤上乙個格仔的狀態,0
表示該格仔上的棋子是固定的,1 表示該格仔上的棋子可以移動或者該格仔是空白的。接下來的 q 行,每行包含 6 個整數依次是
exi、eyi、sxi、syi、txi、tyi,每兩個整數之間用乙個空格隔開,表示每次遊戲空白格仔的位置,指定棋子的初始位置和目標位置。
輸出格式:
輸出檔名為 puzzle.out。
輸出有 q 行,每行包含 1 個整數,表示每次遊戲所需要的最少時間,如果某次遊戲無法完成目標則輸出−1。
輸入樣例#1:
3 4 2輸出樣例#1:0 1 1 1
0 1 1 0
0 1 0 0
3 2 1 2 2 2
1 2 2 2 3 2
2【輸入輸出樣例說明】-1
棋盤上劃叉的格仔是固定的,紅色格仔是目標位置,圓圈表示棋子,其中綠色圓圈表示目標棋子。
第一次遊戲,空白格仔的初始位置是 (3, 2)(圖中空白所示),遊戲的目標是將初始位置在(1, 2)上的棋子(圖中綠色圓圈所代表的棋子)移動到目標位置(2, 2)(圖中紅色的格仔)上。
移動過程如下:
第二次遊戲,空白格仔的初始位置是(1, 2)(圖中空白所示),遊戲的目標是將初始位置在(2, 2)上的棋子(圖中綠色圓圈所示)移動到目標位置 (3, 2)上。
要將指定塊移入目標位置,必須先將空白塊移入目標位置,空白塊要移動到目標位置,必然是從位置(2, 2)上與當前圖中目標位置上的棋子交換位置,之後能與空白塊交換位置的只有當前圖中目標位置上的那個棋子,因此目標棋子永遠無法走到它的目標位置, 遊戲無
法完成。
【資料範圍】
對於 30%的資料,1 ≤ n, m ≤ 10,q = 1;
對於 60%的資料,1 ≤ n, m ≤ 30,q ≤ 10;
對於 100%的資料,1 ≤ n, m ≤ 30,q ≤ 500。
題解:
無聊的花搜題,先建立狀態t[i][j][k][g]表示在(i,j)的棋子的g方向的空格移到k方向需要的步數
預處理亂搞搞出t陣列, 然後t[i][j][k][g]和t[i][j][g][k]建邊,也分別和對應上下建邊,跑spfa即可 難碼..
1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7#define id(x,y,z) ((x)*120+(y)*4+(z))
8using
namespace
std;
9const
int n=35;10
intn,m,q,map[n][n];
11int mx[4]=,my[4]=;
12struct
queueq[n*n*100
];15
int mod=n*n*100
,dis[n][n];
16int head[n*n*4],num=0;17
struct
lina[n*n*100
];20
void init(int x,int y,int
dis)
25void runt(int x,int y,int xx,int yy,int
k)2644}
45if(k==-1)return;46
for(int i=0;i<4;i++)
4752 init(id(x,y,k),id(xx,yy,k^1),1
);53}54
int f[n*n*4],qd[n*n*1000];bool vis[n*n*4
];55
void spfa(int ex,int ey,int sx,int sy,int tx,int
ty)56
68int
x,u;
69while(t!=sum)
7081
}82 vis[x]=false;83
}84int ans=2e9;
85for(int i=0;i<4;i++)if(f[id(tx,ty,i)]f[id(tx,ty,i)];
86if(ans==2e9)printf("
-1\n");
87else printf("
%d\n
",ans);88}
89int
main()
90100
intex,ey,sx,sy,tx,ty;
101for(int i=1;i<=q;i++)
102107 runt(sx,sy,ex,ey,-1
);108
spfa(ex,ey,sx,sy,tx,ty);
109}
110return0;
111 }
題解 noip2013 華容道
題目鏈結 除去多次詢問不談,這道題大致的框架是非常明顯的搜尋。但是雖然是多次詢問,棋盤的狀態是不會變的,並且只有部分的位置是真正有價值的。那麼就可以考慮圖論建模,在這些有價值的狀態上跑從終態到末態的最短路。因為棋子要移動的時候,空白塊一定要移到它的周圍,所以我們可以為這種周圍的位置編號。f x y ...
題解 P1979 華容道 Noip2013
小 b 最近迷上了華容道,可是他總是要花很長的時間才能完成一次。於是,他想到用程式設計來完成華容道 給定一種局面,華容道是否根本就無法完成,如果能完成,最少需要多少時間。小 b 玩的華容道與經典的華容道遊戲略有不同,遊戲規則是這樣的 在乙個 n mn times mn m 棋盤上有 n times ...
NOIP2013提高組day2 華容道
給出一張n m的棋盤,有一些點上有障礙物,其他點上都是棋子。給出q次詢問,每次詢問給出乙個空格,乙個目標棋子,乙個目標位置,每一步可以把乙個棋子移進空格,求把目標棋子移動到目標位置的最小步數。n,m 30,q 500 第一眼看到就知道是大暴力題,發現詢問次數少的時候一次bfs就解決了,那麼詢問多起來...