標籤:io os ar for sp on 代碼 amp size
題意:
就是有n*n*n個木塊,然後給你m條三維的直線
問這些直線能夠消掉多少個木塊
思路:
其實就是求m條直線有幾個交點
然後就是一個雙重迴圈解決
然後讀入的時候需要判重
用三個1000*1000的數組來實現。
注意
3 3
Y=2,Z=2
X=2,Y=2
X=2,Z=2
答案應該是7而不是6,因為三條線交在同一點上。
6的原因是在判斷第一條線的時候 和後面兩個都有交點,但是交點是同一個 其實只有1個。
這裡的判重方法就是,用這條線沒有的那個座標進行判重。
因為對於Y=2,Z=2 交點的話只有X座標不確定,所以用X座標來判重。
代碼:
#include"cstdlib"#include"cstdio"#include"cstring"#include"cmath"#include"queue"#include"algorithm"#include"iostream"using namespace std;int map[22][22];int move[8][2]= {{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1}};int n;struct winpoint{ int cnt,x,y; winpoint() { cnt=x=y=0; }};int dfs(int x,int y,int f,int key){ int xx=x,yy=y; int sum=0; while(1) { sum++; xx+=move[f][0]; yy+=move[f][1]; if(xx<0||yy<0||xx>=15||yy>=15) break; if(map[xx][yy]!=key) break; } return sum;}winpoint ok1(int key){ winpoint ans; for(int i=0; i<15; i++) { for(int j=0; j<15; j++) { if(map[i][j]!=-1) continue; int f=0; for(int k=0; k<4; k++) { if(dfs(i,j,k,key)+dfs(i,j,k+4,key)-1>=5) f=1; if(f) break; } if(f) { if(ans.cnt==0) { ans.x=i; ans.y=j; } ans.cnt++; } } } return ans;}int main(){ while(scanf("%d",&n),n) { memset(map,-1,sizeof(map)); int f=-1; int bl,wh; bl=wh=0; while(n--) { int x,y,z; scanf("%d%d%d",&x,&y,&z); map[x][y]=z; if(z) bl++; else wh++; } /*for(int i=0;i<15;i++) { for(int j=0;j<15;j++) { if(map[i][j]==-1) printf("."); else printf("%d",map[i][j]); } puts(""); }*/ if(bl<wh||bl>=wh+2) //不合法 { puts("Invalid."); continue; } int key; if(bl==wh) key=1; else key=0; winpoint ans; ans=ok1(key); if(ans.cnt>=1) //一步直接贏 { printf("%s",key?"Place black ":"Place white "); printf("at (%d,%d) to win in 1 move.\n",ans.x,ans.y); continue; } ans=ok1(key^1); if(ans.cnt>=2) //兩個必勝點 直接輸 { puts("Lose in 2 moves."); continue; } if(ans.cnt==1) //填對方必勝點 看能否贏 { map[ans.x][ans.y]=key; winpoint tep=ok1(key); if(tep.cnt>=2) //對方堵不住 直接贏 { printf("%s",key?"Place black ":"Place white "); printf("at (%d,%d) to win in 3 moves.\n",ans.x,ans.y); continue; } else //不能則不分勝負 { puts("Cannot win in 3 moves."); continue; } } for(int i=0; i<15; i++) { for(int j=0; j<15; j++) { if(map[i][j]!=-1) continue; map[i][j]=key; winpoint tep=ok1(key); if(tep.cnt>=2) { printf("%s",key?"Place black ":"Place white "); printf("at (%d,%d) to win in 3 moves.\n",i,j); f=1; } if(f==1) break; map[i][j]=-1; } if(f==1) break; } if(f==-1) puts("Cannot win in 3 moves."); } return 0;}
[水+思路] hdu 3682 To Be an Dream Architect