现在的位置: 首页 > 综合 > 正文

poj2706 connect

2013年12月07日 ⁄ 综合 ⁄ 共 2893字 ⁄ 字号 评论关闭

几天都没有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;
}

抱歉!评论已关闭.