今天模拟很有趣,你只要写一份AC代码就能顺便用它来与好友进行k子棋和围棋的混合棋(只是不支持悔棋)。
T1.FIR
期望得分100,实际得分64,(如果有subtask是0分)
这就是那道有趣的题。大模拟……
判断赢我的办法是dfs,分别向八个方向搜索,把相对应的两个方向的答案加上看是否有一个符合。
判断死的话,从一个子开始bfs,遇到同颜色子压入队列,如果周围有一口气就能活,如果搜到最后也没有的话就是死了。
判断吃子的话,找这个子四周的子,遇到一个不同颜色的就开始判死,如果死了的话,我们把棋盘那个位置还原。(我的办法是开一个栈记录一下搜到了哪些子)
判断的顺序是:先不合法(那个位置有棋),再判吃子,再判胜利,如果吃不了子判死亡,没死判胜利。
然后本人因为打了vis标记然后……没用,凉凉。而且还忘了一次能吃好几个子,又凉凉。注意棋盘是无限的,所以其实在边上的子是有气的,而且你还杀不死它。
改完之后就好了,同时也看一下std,非常简洁……只用了我一半的码长……
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<queue> #include<cstring> #include<utility> #include<map> #define pr pair<int,int> #define mp make_pair #define fi first #define sc second #define rep(i,a,n) for(int i = a;i <= n;i++) #define per(i,n,a) for(int i = n;i >= a;i--) #define enter putchar('\n') using namespace std; typedef long long ll; const int M = 100005; const int N = 10000005; int read() { int ans = 0,op = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') op = -1; ch = getchar(); } while(ch >='0' && ch <= '9') { ans *= 10; ans += ch - '0'; ch = getchar(); } return ans * op; } struct node { int x,y; }; int n,p,g[1005][1005],stack[1005][3],top,x,y; int dx[10] = {0,1,1,0,-1,-1,-1,0,1},dy[10] = {0,0,1,1,1,0,-1,-1,-1}; int sx[6] = {0,1,0,-1,0},sy[6] = {0,0,1,0,-1}; bool vis[1005][1005]; queue <node> q; bool pddie(int x,int y,bool f) { bool flag = 0; if(x == 3 && y == 4) flag = 1; while(!q.empty()) q.pop(); q.push((node){x,y}); while(!q.empty()) { node k = q.front(); q.pop(); // if(flag) printf("%d %d\n",k.x,k.y); vis[k.x][k.y] = 1,stack[++top][0] = k.x,stack[top][1] = k.y; rep(i,1,4) { int kx = k.x + sx[i],ky = k.y + sy[i]; if(vis[kx][ky]) continue; //if(kx < 1 || ky < 1) continue; if(g[kx][ky] == -1) { while(top) vis[stack[top][0]][stack[top][1]] = 0,top--; return 0; } else if(g[kx][ky] == f) q.push((node){kx,ky}); } } return 1; } bool pduse(int x,int y) { return g[x][y] != -1; } bool pdeat(int x,int y,bool f) { bool fla = 0; g[x][y] = f; rep(i,1,4) { int kx = x + sx[i],ky = y + sy[i]; if(kx < 1 || ky < 1) continue; if(g[kx][ky] == (f^1)) { // printf("!%d %d\n",kx,ky); if(pddie(kx,ky,f^1)) { // printf("@\n"); while(top) { vis[stack[top][0]][stack[top][1]] = 0; g[stack[top][0]][stack[top][1]] = -1,top--; } fla = 1; } } } g[x][y] = -1; return fla; } int dfs(int x,int y,int dir,bool f) { if(g[x][y] != f) return 0; else if(x < 1 || y < 1) return 0; else return dfs(x + dx[dir],y + dy[dir],dir,f) + 1; } bool pdwin(int x,int y,bool f) { if(dfs(x,y,1,f) + dfs(x,y,5,f) - 1 >= p) return 1; if(dfs(x,y,2,f) + dfs(x,y,6,f) - 1 >= p) return 1; if(dfs(x,y,3,f) + dfs(x,y,7,f) - 1 >= p) return 1; if(dfs(x,y,4,f) + dfs(x,y,8,f) - 1 >= p) return 1; return 0; } void printgraph() { rep(l,1,10) { rep(j,1,10) { if(g[l][j] == 1) putchar('O'); else if(g[l][j] == 0) putchar('X'); else putchar('.'); } enter; } } int main() { freopen("fir.in","r",stdin); freopen("fir.out","w",stdout); memset(g,-1,sizeof(g)); n = read(),p = read(); rep(i,1,n) { x = read(),y = read(); if(pduse(x,y)) printf("illegal\n"),exit(0); else if(pdeat(x,y,i&1)) { g[x][y] = i&1; if(pdwin(x,y,i&1)) { (i&1) ? printf("ITer %d\n",i) : printf("Kitty %d\n",i); return 0; } } else if(pddie(x,y,i&1)) printf("illegal\n"),exit(0); g[x][y] = i&1; if(pdwin(x,y,i&1)) { (i&1) ? printf("ITer %d\n",i) : printf("Kitty %d\n",i); return 0; } // printgraph(); } printf("draw\n"); return 0; }