[计算几何]Submarines

来源:互联网 发布:阿里云翼 编辑:程序博客网 时间:2024/05/24 04:37
Submarines
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 363 Accepted: 162

Description

The Russian navy has, as you probably know, had some problems with their submarines in Swedish waters. These problems are very embarrassing for the Russian military, who has decided to do something about it. 

As a first step in their plan, they want to construct a program for their centre of command to be able to locate their submarines. 

From GPSes (Global Positioning Systems) they are able to get X and Y coordinates for the front and rear points of all submarines. The Russian intelligence has in addition provided data for all islands in the Swedish waters. With this information, and with a lot of help from simulations using GPS equipped minks, Russian programmers have been able to develop a program that, from the information given, tells the user if a submarine is
  1. Still in water
  2. Partially on land
  3. Entirely on land
 

Input

First you will get the number of submarines that are present in the area. [1..100] 
After that, for each submarine, you will get the X and Y positions first for the submarines front and then for its rear. [-1000..1000] Then you will get the number of islands in the area. [1..50]
After that, for each island you will get the following: The number of points of the polygon that represents the island. [3..20], The X and Y positions of the points. [-1000..1000] 
All input are integers. No submarine end point will be on an island edge. No submarine will lie on an island edge. All islands are simple polygons without crossing edges or touching borders. The first point of the island is connected to the last point. All submarines are approximated with a line between the front and rear points. Two islands never overlap or touch each other.

Output

Output contains information about every submarine, in order. 
If the submarine is all in water, print “Submarine X is still in water.” 
If the submarine is all on land, print “Submarine X is completely on land.” 
If the submarine is partially in water and partially on land, print “Submarine X is partially on land.” 
X is the submarine’s number (1,2,3,...) according to it’s order in the input file.

Sample Input

511 11 9 90 0 4 00 1 10 10 6 6 00 -10 0 -924-5 -55 -55 5-5 53-2 -8-1 -9-2 -10

Sample Output

Submarine 1 is still in water.Submarine 2 is completely on land.Submarine 3 is partially on land.Submarine 4 is partially on land.Submarine 5 is still in water.

Source

Svenskt Mästerskap i Programmering/Norgesmesterskapet 2001


几何题一定要小心重叠问题,本题中说不会有交叉,有误导性,因为实际上潜艇是可以和岛的边有重合,或者潜艇的点在岛边上的。
所以判断外积的符号时要格外小心。比如,此题点在边上是算作在内部的。

#include <cstdio>#define REP(a,b) for (int (a)=1;a<=b;a++)struct node{    int x,y;    node(){}    node(int xx,int yy):x(xx),y(yy){}    node operator-(const node& n2)    {        return node(x-n2.x,y-n2.y);    }};int n,m,count[110];node sub[110][2];node pos[110][110];int CRP(node a,node b){    return a.x*b.y-a.y*b.x;}bool opposite(int a,int b){    return (a<0)==(b>=0);}int work(int l){    node f = sub[l][0];    node r = sub[l][1];    REP(i,100){}    REP(i,m)    {        int crp1 = CRP(pos[i][1]-pos[i][0],f-pos[i][0]);        int crp2 = CRP(pos[i][1]-pos[i][0],r-pos[i][0]);        bool onisland = true;        REP(j,count[i])        {            int crp3,crp4;            crp3 = CRP(pos[i][j]-pos[i][j-1],f-pos[i][j-1]);            crp4 = CRP(pos[i][j]-pos[i][j-1],r-pos[i][j-1]);            if (opposite(crp1,crp3) || opposite(crp2,crp4))            {                onisland = false;                break;            }        }        if (onisland) return 0;    }    REP(i,m)    {        REP(j,count[i])        {            int crp1 = CRP(pos[i][j]-pos[i][j-1],f-pos[i][j-1]);            int crp2 = CRP(pos[i][j]-pos[i][j-1],r-pos[i][j-1]);            if (opposite(crp1,crp2))            {                crp1 = CRP(r-f,pos[i][j]-f);                crp2 = CRP(r-f,pos[i][j-1]-f);                if (opposite(crp1,crp2))                    return 1;            }        }    }    return 2;}int main(){    scanf("%d",&n);    REP(i,n)    {        int a,b,c,d;        scanf("%d%d%d%d",&a,&b,&c,&d);        sub[i][0] = node(a,b);        sub[i][1] = node(c,d);    }    scanf("%d",&m);    REP(i,m)    {        scanf("%d",count+i);        REP(j,count[i])        {            int x,y;            scanf("%d%d",&x,&y);            pos[i][j] = node(x,y);        }        pos[i][0] = pos[i][count[i]];    }    REP(i,n)    {        printf("Submarine %d",i);        switch(work(i))        {            case 0:                printf(" is completely on land.\n");                break;            case 1:                printf(" is partially on land.\n");                break;            default:                printf(" is still in water.\n");                break;        }    }    return 0;}


原创粉丝点击