几天都没有A题了,稍微分析了一下就是理解题意的能力太差了,比如之前的一道题,明明思路很简单,没有算法难度,但是我看不懂题意啊,想了两天,然后问了别人的题意,但是还是花了大半天时间才将题中给的数据给过了。。。。然后到现在还没有AC,一直wa了,看了和别人的思路是一样的,不过没有怎么看他们的代码,觉得这样的题等几天自己再写一下,把我的脑袋彻底弄混乱了,再说这题,我也是读错了好久,而且一开始的算法是想省事的,然后就有漏洞了,然后不断的改啊,又重写才过的!题不难但是功夫深啊!
题目大意:对弈,黑棋先下,黑棋胜利就是纵坐标的连线可以从0到n,白棋的胜利就是横坐标的连线可以从0到n,其中颜色相同的棋子连线的前提是他们的横纵坐标分别相差2和三并且没有别的以连的线相交,题目要求你判断是不是最后一步棋可以下出胜利的棋局。
解题思路:对黑棋最后一步之前进行判断看是否出现赢的局面,然后最后一步下完再判断是否赢的局面,然后输出结果。我的最大失误就是判断线段是否相交的时候用的差乘个写错了,然后各种纠结各种改,不过还好的是差乘写错的时候连题中给的数据都没有过,这样就好改多啦!发现近来写的程序很多都是连题中给的输入输出样例都没有过啊!
#include<iostream> #include<cstdio> #include<cstring> #include<climits> #include<queue> #include<stack> #include<vector> using namespace std; #define rep(i,n) for(int i=0;i<(n);i++) #define repf(i, a, b) for (int i=(a); i<=(b); ++i) #define repd(i, a, b) for (int i=(a); i>=(b); --i) #define max(a,b) (a)>(b)?(a):(b) #define min(a,b) (a)<(b)?(a):(b) #define exp 0.000000000001 #define N 10000000 int map[30][30]; bool link[625][10]; int n,m; int trans[8][2]={-2,-1,-1,-2,-1,2,2,-1,-2,1,1,-2,1,2,2,1}; int find(int x,int y,int x1,int y1,int sign) { int maxx=max(x,x1); int maxy=max(y,y1); int minx=min(x,x1); int miny=min(y,y1); int i,j,k,s,t,p=0; for(i=minx; i<=maxx; i++) { for(j=miny; j<=maxy; j++) { if((i==x && j==y) || (i==x1 && j==y1)) continue;//本身的点的 if(map[i][j]==0)//就是本身没有点的 continue; for(k=0; k<8; k++) { s=i+trans[k][0]; t=j+trans[k][1]; if(s<0 || s>n || t<0 || t>n ) continue; if(map[s][t]==0 || map[s][t]!=map[i][j]) continue;//代表两个是不可以连线的 //(x,y),(x1,y1),(i,j),(s,t)/这两条线段是否有交点 if(((x-s)*(j-t)-(y-t)*(i-s))*((i-s)*(y1-t)-(j-t)*(x1-s))>0 && ((s-x)*(y1-y)-(t-y)*(x1-x))*((x1-x)*(j-y)-(y1-y)*(i-x))>0)//可以相交的 // if(pan(x,y,x1,y1,s,t,i,j)) {//就是有一个阻挡住就是不能相交的 // printf("%d\n",((x-s)*(j-t)-(y-t)*(i-s))*((i-s)*(y1-t)-(j-t)*(x1-s))); if(link[i*(n+1)+j][k]==true)//然后是已经连线了 { p=1; return 0; } } } } } if(p==0) return 1; return 0; } void fun(int i,int j,int sign) { int k,x,y; for(k=0; k<8; k++) { x=i+trans[k][0]; y=j+trans[k][1]; if(x<0 ||x>n || y<0 || y>n) continue; if(map[x][y]!=sign)//直接就没有了 continue; if(find(x,y,i,j,sign))//没有阻挡的 { link[i*(n+1)+j][k]=true;//就是旁边的k个相连的 link[x*(n+1)+y][7-k]=true; } } } int judge() { int i,j; queue<int>q; bool vis[30][30]; for(i=0; i<30; i++) for(j=0; j<30; j++) vis[i][j]=true; int sign=0; int s,t,k; for(i=0; i<=n; i++) { if(map[i][0]==1 && vis[i][0]==true) q.push(i*(n+1)+0); while(!q.empty()) { int pre=q.front(); q.pop(); int x=pre/(n+1); int y=pre%(n+1); vis[x][y]=false; for(k=0; k<8; k++) { if(link[pre][k]==false) continue; s=x+trans[k][0]; t=y+trans[k][1]; if(s<0 || s>n || t<0 || t>n) continue; if(t==n) { sign=1; break; } if(vis[s][t]==true) q.push(s*(n+1)+t); } } if(sign==1) break; } if(sign==1) return 1; else return 0; } int main() { int i,j,x,y; while(true) { int sign1=0,sign2=0; scanf("%d%d",&n,&m); if(n==0 && m==0) break; for(i=0; i<=620; i++) for(j=0; j<8; j++) link[i][j]=false; for(i=0; i<=n; i++) for(j=0; j<=n; j++) map[i][j]=0; for(i=0; i<m-1; i++) { scanf("%d%d",&y,&x); if(i%2==0) { map[x][y]=1; fun(x,y,1); } else { map[x][y]=2; fun(x,y,2); } } sign1=judge(); scanf("%d%d",&y,&x); map[x][y]=1; fun(x,y,1); sign2=judge(); if(sign1==0 && sign2==1) printf("yes\n"); else printf("no\n"); } return 0; }