poj2706 connect

来源:互联网 发布:皇家猫粮淘宝假货多吗 编辑:程序博客网 时间:2024/04/28 21:09

几天都没有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 10000000int 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;elsereturn 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");elseprintf("no\n"); } return 0;}