UVALive 7008

来源:互联网 发布:adobe家族软件 编辑:程序博客网 时间:2024/06/03 16:50

This problem is about a war game between two countries. To protect a base, your country built a
defense system called “Tactical Multiple Defense System” (TMD system in short). There are two
weapons in the TMD system: Line gun and Circle gun. The Line gun can in one shot destroy all
targets whose (two-dimensional) coordinates are on the same ray from the base, and the Circle gun
can in one shot destroy all the targets with the same distance to the base. Note that in this game the
coordinate of the base is (0, 0).
The other country is going to attack the base of your country. They deploy missiles at some places
according to their “National Missile Deployment Plan” (NMD plan). Your spy got the NMD plan and
therefore you have the positions of all the missiles, which are the targets you need to destroy. As the
commander of the TMD system, your mission is to determine how to destroy all the n missiles by Line
gun and Circle gun with minimum number of total shots.
The position P i of a missile is given by three positive integers r i , s i , t i which indicates the polar
coordinate is (r i , arctan(t i /s i )), i.e., the distance from the base to P i is r i and the slope of the ray
from the base and through P i is t i /s i . We shall say that P i is on the ray of slope t i /s i . To use the
Line gun, you input two integer parameters t and s, press the fire button, and then it destroys all
targets (missiles) on the ray of slope t/s. On the other hand, to use the Circle gun, you need to input
a positive integer parameter r, and it can destroy all targets with distance r to the base, that is, it
destroys targets exactly on the circle of radius r (but not the ones within the circle). Figure 8 illustrates
some examples.
Figure 8: (a) A shot of Circle gun destroys four missiles on the same circle. (b) Two shots of Line
gun. Three and two missiles are destroyed by the two shots, respectively. (c) Destroying all eight
missiles by three shots.
Technical Specification
• The number of missiles n is at most 20000 in each test case. It is possible that two missiles are
at the same position.
• The three parameters (r i , s i , t i ) of each position are integers and satisfy 1000 < r i ≤ 6000 and
1 ≤ s i , t i ≤ 10000.
Input
The first line contains an integer T indicating the number of test cases. There are at most 10 test
cases. For each test case, the first line is the number of missiles n. Each of the next n lines contains
the parameters r i , s i , t i of one missile, and two consecutive integers are separated by a space.
Output
For each test case, output in one line the minimum number of shots to destroy all the missiles.
Sample Input
1
5
1010
1020
1030
1030
1030
1
2
3
9
9
2
4
6
9
1
Sample Output
2

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <map>#include <set>#include <queue>#include <stack>#include <cmath>#define LL long long#define INF 0x3f3f3f3f#define RR freopen("in.txt","r",stdin)#define WW freopen("out.txt","w",stdout)using namespace std;const int maxn = 20000+10;map<double,int >map1;map<int,int >map2;int cnt,head[maxn],vis[maxn],link[maxn],cnt1,cnt2;struct node{    int u,v,next;} edge[maxn];void add(int u,int v){    edge[cnt].v = v;    edge[cnt].next = head[u];    head[u] = cnt++;}int dfs(int u){    for(int i=head[u]; i!=-1; i=edge[i].next)    {        int v = edge[i].v;        if(vis[v])            continue;        vis[v] = true;        if(link[v] == -1 || dfs(link[v]))        {            link[v] = u;            return 1;        }    }    return 0;}void hungary(){    int ans = 0;    memset(link,-1,sizeof(link));    for(int i=0; i<cnt1; i++)    {        memset(vis,false,sizeof(vis));        ans += dfs(i);    }    printf("%d\n",ans);}int main(){    RR;    int T;    int n,x,y,z;    double tmp;    scanf("%d",&T);    while(T--)    {        memset(head,-1,sizeof(head));        cnt = 0;        map1.clear();        map2.clear();        scanf("%d",&n);        cnt1 = 0;        cnt2 = n;        for(int i=0; i<n; i++)        {            scanf("%d%d%d",&x,&y,&z);            tmp = z * 1.0 / y;            if(map2.find(x) == map2.end())            {                map2[x] = cnt1++;            }            if(map1.find(tmp) == map1.end())            {                map1[tmp] = cnt2++;            }            add(map2[x],map1[tmp]);        }        hungary();    }    return 0;}



0 0
原创粉丝点击