poj 2706 Connect
来源:互联网 发布:过亿收入的淘宝店铺 编辑:程序博客网 时间:2024/06/05 08:51
题意:给你一个N+1*N+1的棋盘(从0到N),给定了这局棋的下棋过程,黑子先下,且总的下棋步数为奇数,也就保证最后一个下的是黑棋。其中,每下一步棋如果它的周围(中国象棋或是国际象棋中一个日字的走法)8个点存在同色的棋,并且两个棋之间没有其他棋子连线所拦,那么就将这连个棋子连线。如果黑棋从左边界到右边界有一条线贯穿或白棋从上边界到下边界有一条线贯穿,贯穿的那方就获得胜利。原题意为问黑子的最后一步是否能使得这局棋分出胜负。实际上题意有所差错,在所有棋子下完之后只需要判断是否存在赢家即可(无论黑白)当存在赢家输出yes,黑白均没胜利输出no。
思路:首先必不可少的是判线段是否相交,其次,就是怎么去模拟了。本人用的是完全无脑模拟,就是黑棋一步白棋一步,单独记录黑棋和白棋的每个坐标每当下棋之后就与其他坐标想比对,看看是否在存在8点之一,若存在那么先连线(但不存储)将连线与所有黑白连线比较,看看是否存在相交,当不存在的时候就把黑线存入黑线的存储结构里,白棋同理。最后一遍循环跑完,检查是否有左右或上下贯通。检查联通可使用并查集,将坐标化为一个独立的数值即可。
#include <iostream>#include <algorithm>#include <cstdlib>#include <cstring>#include <cstdio>#include <cmath>#define eps 1e-8#define zero(x) (((x) > 0 ? (x) : (x)) < eps)using namespace std;struct Point { double x,y; };struct Line { Point a,b; };struct P{ int x,y;};int arr1[700],arr2[700];double xmult(Point p1, Point p2, Point p){ return (p1.x - p.x)*(p2.y - p.y)-(p2.x-p.x)*(p1.y-p.y);}bool isIntersected(Line u,Line v){ return (max(u.a.x,u.b.x)>=min(v.a.x,v.b.x)) && (max(v.a.x,v.b.x)>=min(u.a.x,u.b.x)) && (max(u.a.y,u.b.y)>=min(v.a.y,v.b.y)) && (max(v.a.y,v.b.y)>=min(u.a.y,u.b.y)) && (xmult(u.a,v.a,u.b)*xmult(u.a,u.b,v.b) > eps)&& (xmult(v.a,u.a,v.b)*xmult(v.a,v.b,u.b) > eps);}void init(){ for(int i=0;i<=700;i++) { arr1[i]=arr2[i]=i; }}int Find1(int r){ return r==arr1[r]?r:arr1[r]=Find1(arr1[r]);}int Find2(int r){ return r==arr2[r]?r:arr2[r]=Find2(arr2[r]);}void Union1(int x,int y){ int fx=Find1(x); int fy=Find1(y); if(fx!=fy) { arr1[fx]=fy; }}void Union2(int x,int y){ int fx=Find2(x); int fy=Find2(y); if(fx!=fy) { arr2[fx]=fy; }}int main(){ int n,m; int x,y; int k; while(scanf("%d%d",&n,&m),n||m) { init(); int flag; int t1=0,t2=0; int l1=0,l2=0; P p_black[200],p_white[200]; Line black[200],white[200],line; for(int i=0;i<m;i++) { scanf("%d%d",&x,&y); if(i%2==0){ for(int j=0;j<t1;j++) { flag=0; if((abs(p_black[j].x-x)==2&&abs(p_black[j].y-y)==1)|| (abs(p_black[j].x-x)==1&&abs(p_black[j].y-y)==2)) { line.a.x=x; line.a.y=y; line.b.x=p_black[j].x; line.b.y=p_black[j].y; for(k=0;k<l2;k++) { if(isIntersected(line,white[k])) {flag=1; break;} } for(k=0;k<l1;k++) { if(isIntersected(line,black[k])) {flag=1; break;} } if(!flag) { black[l1].a.x=line.a.x; black[l1].a.y=line.a.y; black[l1].b.x=line.b.x; black[l1].b.y=line.b.y; l1++; Union1(x*30+y,p_black[j].x*30+p_black[j].y); } } } p_black[t1].x=x; p_black[t1++].y=y; } else { for(int j=0;j<t2;j++) { flag=0; if((abs(p_white[j].x-x)==2&&abs(p_white[j].y-y)==1)|| (abs(p_white[j].x-x)==1&&abs(p_white[j].y-y)==2)) { line.a.x=x; line.a.y=y; line.b.x=p_white[j].x; line.b.y=p_white[j].y; for(k=0;k<l2;k++) { if(isIntersected(line,white[k])) {flag=1; break;} } for(k=0;k<l1;k++) { if(isIntersected(line,black[k])) {flag=1; break;} } if(!flag) { white[l2].a.x=line.a.x; white[l2].a.y=line.a.y; white[l2].b.x=line.b.x; white[l2].b.y=line.b.y; l2++; Union2(x*30+y,p_white[j].x*30+p_white[j].y); } } } p_white[t2].x=x; p_white[t2++].y=y; } } flag=0; for(int i=0;i<=n;i++) { for(int j=0;j<=n;j++) { if(Find1(i)==Find1(n*30+j)||Find2(i)==Find2(n*30+j)){ printf("yes\n"); flag=1; break; } } if(flag) break; } if(!flag) printf("no\n"); } return 0;}
0 0
- POJ 2706 Connect
- POJ 2706 Connect
- poj 2706 Connect
- poj 2706 Connect
- POJ 2706 Connect BFS + 判断线段相交
- poj--2706--Connect(极限大模拟)
- CONNECT
- connect
- connect
- connect()
- Connect
- connect
- connect
- CONNECT
- Connect
- connect
- connect
- connect()
- 使用SoapObject登入网站获取通行证
- 《Java编程思想》第七章 复用类
- Vigenère密码题解
- Maven的配置
- JavaBean与jsp的动作
- poj 2706 Connect
- Python爬虫入门(8):Beautiful Soup的用法
- 5. Longest Palindromic Substring 找出给定字符串中最长的子字符串
- 用css伪元素实现tooltip效果
- opencv学习笔记(二十三)——相机标定原理详解
- HDU——2091空心三角形
- android:visibility的三种属性
- POJ 1260 Pearls DP
- HDU1561 The more,The Better(树形DP+背包)