UVaLive 6693 Flow Game (计算几何,线段相交)

题意:给个棋盘,你可以在棋盘的边缘处放2个蓝色棋子2个黄色棋子,问连接2组同色棋子的最小代价,如果线路交叉,输-1。

析:交叉么,可以把它们看成是两条线段,然后如果相交就是不行的,但是有几种特殊情况,比如都在同一行或同一列,要特殊考虑这种情况。

1122,1212,2211,2121,1221,2112.这是几种特殊的,然后其他的就可以用判交叉来算了,然后最短路就是横纵坐标相减的绝对值加2.

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <stack>
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std;

typedef long long LL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const LL LNF = 100000000000000000;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 3e5 + 5;
const int mod = 1e9 + 7;
const char *mark = "+-*";
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
int n, m;
inline bool is_in(int r, int c){
    return r >= 0 && r < n && c >= 0 && c < m;
}
inline LL Max(LL a, LL b){  return a < b ? b : a; }
inline LL Min(LL a, LL b){  return a > b ? b : a; }
inline int Max(int a, int b){  return a < b ? b : a; }
inline int Min(int a, int b){  return a > b ? b : a; }
char s[15][15];
vector<P> v1;
vector<P> v2;

inline int mult(const P &a, const P &b, const P &c){
    return (a.first-c.first)*(b.second-c.second) - (b.first-c.first)*(a.second-c.second);
}

bool intersection(const P &aa, const P &bb, const P &cc, const P &dd){
    if(Max(aa.first, bb.first) < Min(cc.first, dd.first))  return false;
    if(Max(aa.second, bb.second) < Min(cc.second, dd.second))  return false;
    if(Max(cc.first, dd.first) < Min(aa.first, bb.first))  return false;
    if(Max(cc.second, dd.second) < Min(aa.second, bb.second))  return false;
    if(mult(cc, bb, aa) * mult(bb, dd, aa) < 0)  return false;
    if(mult(aa, dd, cc) * mult(dd, bb, cc) < 0)  return false;
    return true;
}

bool solve(int a, int b, int c, int d){
    if(a < b && b < c && c < d){  printf("%d\n", b-a+d-c+2);  return true; }
    else if(c < d && d < a && a < b){  printf("%d\n", b-a+d-c+2);  return true; }
    else if(a < c && c < d && d < b){  printf("%d\n", b-a+d-c+4);  return true; }
    else if(c < a && a < b && b < d){  printf("%d\n", b-a+d-c+4);  return true; }
    else if(a < c && c < b && b < d){  printf("-1\n");  return true; }
    else if(c < a && a < d && d < b){  printf("-1\n");  return true; }

    return false;
}

bool judge1(){
    bool ok = true;
    if(v1[0].first == v1[1].first && v1[1].first == v2[0].first && v1[1].first == v2[1].first){
        if(solve(v1[0].second, v1[1].second, v2[0].second, v2[1].second))  return true;
    }
    else if(v1[0].second == v1[1].second && v1[1].second == v2[0].second && v1[1].second == v2[1].second){
        if(solve(v1[0].first, v1[1].first, v2[0].first, v2[1].first))  return true;
    }
    return false;
}

int main(){
    int T;  cin >> T;
    while(T--){
            v1.clear();  v2.clear();
            scanf("%d", &n);
            for(int i = 1; i <= n; ++i) scanf("%s", s[i]+1);
            for(int i = 1; i <= n; ++i)
                for(int j = 1; j <= n; ++j)
                    if(s[i][j] == ‘1‘)   v1.push_back(P(i, j));
                    else if(s[i][j] == ‘2‘)  v2.push_back(P(i, j));
            sort(v1.begin(), v1.end());
            sort(v2.begin(), v2.end());
            if(judge1())  continue;
            if(intersection(v1[0], v1[1], v2[0], v2[1])){  printf("-1\n"); continue; }
            printf("%d\n", abs(v1[1].first-v1[0].first)+abs(v1[1].second-v1[0].second)+abs(v2[1].first-v2[0].first)+abs(v2[1].second-v2[0].second)+2);
    }
    return 0;
}
时间: 2024-08-06 12:28:32

UVaLive 6693 Flow Game (计算几何,线段相交)的相关文章

poj1039(计算几何)线段相交

题意:给一个管道求光线能穿到的最大x坐标. 解法:通过旋转光线一定可以使得光线接触一个上点和一个下点.枚举接触的上下点,然后逐一判断光线是否穿过每个拐点面.碰到一个拐点面没有穿过的,则是因为与其左边线段相交,求出直线与线段交点更新答案即可.不想交则说明在前一个拐点已经穿出去了. 代码: /****************************************************** * author:xiefubao ********************************

德莱联盟 计算几何 线段相交

难度:1 描述 欢迎来到德莱联盟.... 德莱文... 德莱文在逃跑,卡兹克在追.... 我们知道德莱文的起点和终点坐标,我们也知道卡兹克的起点和 终点坐标,问:卡兹克有可能和德莱文相遇吗?,并且保证他们走的都是直线. 输入 几组数据,一个整数T表示T组数据每组数据 8个实数,分别表示德莱文的起点和终点坐标,以及卡兹克的起点和终点坐标 输出 如果可能 输出 Interseetion,否则输出 Not Interseetion 样例输入 2 -19.74 7.14 22.23 -27.45 -38

POJ2284 That Nice Euler Circuit (欧拉公式)(计算几何 线段相交问题)

That Nice Euler Circuit Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 1977   Accepted: 626 Description Little Joey invented a scrabble machine that he called Euler, after the great mathematician. In his primary school Joey heard about

UVAlive 6693 Flow Game(模拟)

题目地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4705 思路:若有解,两点连线最小距离=曼哈顿距离+1,则ans=abs(x1-x2)+abs(y1-y2)+abs(x3-x4)+abs(y3-y4)+2.若无解,则两线相交:对于边界,逆时针遍历,若1212或2121则此时无解,其他情况有解.注意所有点在同一行或同

POJ 3347 Kadj Squares (计算几何+线段相交)

题意:从左至右给你n个正方形的边长,接着这些正方形都按照旋转45度以一角为底放置坐标轴上,最左边的正方形左端点抵住y轴,后面的正方形依次紧贴前面所有正方形放置,问从上方向下看去,有哪些正方形是可以被看到的(如图) 题解:首先我们找到每个正方形左右端点的坐标转化为一条线段,接着我们寻找哪些线段被其他某些条线段覆盖,这些被覆盖的线段就不能被看到 寻找被覆盖的线段利用区贪心间,我们按照左端点升序.左端点相同右端点降序排序,则左端点一定被前面的线段覆盖,接着对于右端点使用单调栈的思想寻找可以看到的线段就

POJ 3304 Segments(计算几何:直线与线段相交)

POJ 3304 Segments 大意:给你一些线段,找出一条直线能够穿过所有的线段,相交包括端点. 思路:遍历所有的端点,取两个点形成直线,判断直线是否与所有线段相交,如果存在这样的直线,输出Yes,但是注意去重. struct Point { double x, y; } P[210]; struct Line { Point a, b; } L[110]; double xmult(Point p1, Point p2, Point p) { return (p1.x-p.x)*(p2.

Pick-up sticks(计算几何_线段相交)

Description Stan has n sticks of various length. He throws them one at a time on the floor in a random way. After finishing throwing, Stan tries to find the top sticks, that is these sticks such that there is no stick on top of them. Stan has noticed

【TOJ 1288】计算几何练习题――线段相交(模板题)

描述 线段相交测试在计算几何中是经常用到的,给定线段P1P2(P1和P2是线段的两端点,且不重合).P3P4(P3和P4是线段的两端点,且不重合),判断P1P2和P3P4是否相交.P1P2和P3P4不重合,即指只存在一个点P,它既落在P1P2上又落在P3P4上(含线段的端点). 输入 输入数据有多组,第一行为测试数据的组数N,下面包括2N行,每组测试数据含2行,第一行为P1P2的坐标值,第二行为P3P4的坐标值,比如下面的数据10 0 1 12 2 3 3表示P1.P2.P3.P4的坐标分别为:

poj 1127 -- Jack Straws(计算几何判断两线段相交 + 并查集)

Jack Straws In the game of Jack Straws, a number of plastic or wooden "straws" are dumped on the table and players try to remove them one-by-one without disturbing the other straws. Here, we are only concerned with if various pairs of straws are