推箱子
是一款經典遊戲。如圖所示,灰色格子代表不能通過區域,藍色方格是箱子,黑色圓形代表玩家,含有圓點的格子代表目標點。
規定以下規則:
1、一局遊戲中只會有一個箱子,一個玩家和一個目標點。
2、通過方向鍵控制玩家移動。
3、圖中的灰色格子代表牆壁,玩家與箱子都不能通過。
4、推到牆壁的箱子,就無法再將箱子推離牆壁,因爲玩家無法到達箱子靠牆壁的一側去推箱子。也就是說箱子只能以“被推”的方式被移動,不是以“被拉”的方式被移動。但如果玩家將箱子推至牆壁後,垂直牆壁的兩側沒有阻礙物,則玩家可以朝這兩個不同的方向推移箱子。如果箱子進入角落,就沒有辦法再推動這個箱子了。
5、玩家是不能走出場景的。玩家推着箱子到達場景邊緣,如果繼續點擊使玩家和箱子向牆壁前進的方向鍵,箱子和人都會保持不動。玩家的前進方向上如果有牆壁,也是不能前進的。但是這些點擊都視爲合理的輸入。
6、箱子一旦到達目標點,就不能再移動了。但這時,玩家仍然可以在場景內自由行動。如果繼續嘗試推箱子,那麼玩家將會和箱子一起保持在原地不動。
現在,給出一種方向鍵的點擊方案,請判斷,這種方案是否能使箱子最終停在目標點上。爲了方便表示,我們以0代表空白格子,以4代表不能通過區域,以1代表玩家,以3代表箱子,以2代表目標點。
輸入
第一行數據包含三個整數,N,M,S。其中,N(0 < N <= 100)代表格子的寬度,M(0 < M <= 100)代表格子的高度,S(0 < S <= 200)代表測試點的個數。
接下來的M行,每行都會有N個字符,描述當前的盤面。
接下來的S行,每行都代表一個測試點。每行都以一個整數T(0 < T <= 10000)開頭,接下來是一個空格和T個字符。這T個字符僅由d,u,l,r這四個字母組成,分別代表了敲擊向下,向上,向左,向右的方向鍵。
輸出
對於每個測試點,輸出最後箱子是否在目標點上。如果是,輸出YES,如果不是,則輸出NO。
5 4 3 00000 13000 00200 00000 4 rurd 6 urdldr 6 rrrurd
樣例輸出 yes yes no
#include <iostream>
#include <vector>
#include <map>
using namespace std;
int main(){
int n, m , s;
cin>>n>>m>>s;
vector<vector<int> > bd(m, vector<int>(n));
int sy, sx;
int ey, ex;
int by, bx;
for(int i = 0; i<m; i++){
for(int j = 0; j<n; j++){
char t; cin>>t; t-='0';
if(t==1) {sy = i, sx = j;}
else if(t==2) {ey = i, ex = j;}
else if(t==3) {by = i, bx = j;}
bd[i][j] = t!=4;
//1: no brick, 0:brick
}
}
for(int i = 0; i<s; i++){
int cnt; char c;
cin>>cnt;
int x = sx, y = sy;
int tx = sx, ty = sy;
int rx = bx, ry = by;
int j;
for(j = 0; j<cnt; j++){
//cout<<y<<","<<x<<endl;
cin>>c;
switch(c){
case 'r': tx = x+1; ty = y; break; //@error 1: 後面一句話ty=y忘記寫了,因爲tx,ty都有可能是髒數據而和x,y不同步。下同
case 'u': ty = y-1; tx = x; break;
case 'd': ty = y+1; tx = x; break;
case 'l': tx = x-1; ty = y; break;
break;
}
if(tx <0 || ty <0 || tx>= n || ty>=m || bd[ty][tx] == 0) continue;
if(ty == ry && tx == rx){
if(ty == ey && tx == ex) continue;
int xx = 2*tx - x, yy = 2*ty - y;
if(xx <0 || yy <0 || xx>= n || yy>=m || bd[yy][xx] ==0) continue;
rx = xx, ry = yy;
}
x = tx, y = ty;
}
if(rx!=ex || ry!=ey) {cout<<"NO"<<endl;}
else cout<<"YES"<<endl;
}
return 0;
}
很水的一道題,關鍵是記錄箱子座標(bx, by), 人座標(sx,sy), 然後用vector<vector<>>記錄地圖(有無牆壁) 但是在人移動時,需要臨時座標tx,ty和xx,yy,計算臨時座標的時候注意了(見註釋error 1)
井字棋
井字棋,又稱爲井字遊戲、井字過三關等,是種紙筆遊戲。其具體玩法爲:
兩個玩家,一個打圈(O),一個打叉(X),輪流在3乘3的格上打自己的符號,最先以橫、直、斜連成一線則爲勝。當9個格子畫滿,雙方均無法取勝時,則爲和局。當有玩家取勝或者下成平局後,比賽結束。
假設每次X方均爲先手,給出一個局面,請你判斷這個局面是否合法,如果局面合法,則判斷當前局面是否是比賽結束局面,如果是,則判斷當前局面是X方勝利,O方勝利或者是平局。如果局面暫時未分勝負,則判斷下一個下棋的選手下完一步後(假設採用最優策略)能否取勝。
輸入
每個輸入數據包含多個測試點。
第一行爲測試點的個數S <= 2000。之後是S個測試點的數據。
每個測試點的數據包括3行,用於描述整個棋盤。每行包含一個長度爲3的字符串,取值範圍爲{'_', 'O', 'X'},其中'_'表示該格子爲空,'X'表示該格被先手者佔領,'O'表示該格被後手者佔領。
每個測試點之間會有一個空行相隔。
輸出
對於每個測試點,對應的結果輸出一行。
如果局面非法,則輸出"Invalid"。
否則如果局面是比賽結束局面,X取勝則輸出"X win", O取勝則輸出"O win", 如果是平局則輸出"Draw"。
如果局面合法並且不是比賽結束的局面,則判斷下一個下棋的選手下完一步後能否取勝,如果可以,則輸出"Next win", 否則輸出"Next cannot win"。
注意,所有的結果輸出均不帶引號。
樣例提示
第一個例子,因爲X先下,所以該局面不可能出現。
第二個例子,爲結束局面,X取勝。
第三個例子,全部格子下完,雙方均無法取勝,平局。
第四個例子,局面未分勝負,下一個下的是X,可以取勝。
第五個例子,局面未分勝負,下一個下的是O,無論下到哪一個格子均無法取勝。
5 __O _XO ___ XXX ___ OO_ XXO OOX XXO X_X OO_ ___ XO_ XX_ __O
樣例輸出
#include <iostream>
using namespace std;
char t[3][3];
#define MIN -999
int findline(char c){
int mcnt = -1;
for(int i = 0 ; i<3; i++){
int ijcnt = 0, jicnt = 0;
for(int j = 0; j<3; j++){
if(t[i][j]==c) ijcnt++;
else if(t[i][j]!='_') ijcnt=MIN;
if(t[j][i]==c) jicnt++;
else if(t[j][i]!='_') jicnt=MIN;
}
mcnt = max(mcnt, ijcnt);
mcnt = max(mcnt, jicnt);
}
int iicnt = 0, jjcnt = 0;
for(int i = 0; i<3; i++){
if(t[i][i] ==c) iicnt ++;
else if(t[i][i] !='_') iicnt=MIN;
}
for(int i = 0; i<3; i++){
if(t[i][2-i] ==c) jjcnt ++;
else if(t[i][2-i] !='_') jjcnt=MIN;
}
mcnt = max(mcnt, iicnt);
mcnt = max(mcnt, jjcnt);
return mcnt;
}
int main(){
int n; cin>>n;
for(int c = 0; c<n; c++){
int cx = 0, co = 0;
for(int i = 0; i<3; i++){
for(int j = 0; j<3; j++){
char ch ; cin>>ch;
//cout<<ch<<":"<<endl;
if(ch =='X') cx ++;
else if(ch =='O') co ++;
t[i][j] = ch;
}
}
if(co>cx || cx>co+1) {cout<<"Invalid"<<endl; continue;}
int x = findline('X'), y = findline('O');
if(x==3 && y==3) {cout<<"Invalid"<<endl; continue;}
if(x==3) {cout<<"X win"<<endl;continue;}
if(y==3) {cout<<"O win"<<endl;continue;}
if(co + cx == 9 || x<0 && y<0) {cout<<"Draw"<<endl;continue;}
if(cx==co){
if(x == 2) cout<<"Next win"<<endl;
else cout<<"Next cannot win"<<endl;
}
else {
if(y == 2) cout<<"Next win"<<endl;
else cout<<"Next cannot win"<<endl;
}
}
return 0;
}
不知道爲什麼會錯。