Easy billiards (zoj 3761 并查集+DFS)

原创 2015年07月08日 22:43:44

Easy billiards

Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge

Edward think a game of billiards is too long and boring. So he invented a new game called Easy billiards.

Easy billiards has N balls on a brimless rectangular table in the beginning, and your goal is try to make the number of balls on the table as least as possible by several hit under the following rules:

1: The direction you hit the balls should parallel to the tables border.

2: If ball A crashed into ball B, ball B will moves in the same direction of ball A before the crashing, and ball A will stop in the place of ball B before the crashing.

3: If ball C is moving and there are no balls in front of ball C, it will runs out of the tables border, that means ball C is out of the table.

4: You can choose arbitrary ball on the table to hit, but on a hit, you can't let the ball you choose to hit runs out of the tables border. In another word, a ball could runs out of the table if and only if it was crashed by another ball in a hitting.

Now, Edward wants to know the least number of balls remained on the table after several hits, and how.

Input

There are multiple test cases. For each test cases, in the first line, there is an integer N, which means the number of the balls on the table. There are following N lines, each line contains two integers Xi and Yi, which means the coordinate of ball I. (0<=N<=2000, 0<=Xi, Yi<=10^8)

Output

For each test cases, you should output the least number of balls on the first line.And you should output several lines to show the order of hits following the first line, each line should contains the coordinate of the ball you choose to hit and the direction you hit. (LEFT,RIGHT,UP,DOWN).

Sample Input

4
0 0
2 0
4 0
2 2
9
1 1
2 1
3 1
1 2
2 2
3 2
1 3
2 3
3 3

Sample output

1
(2, 2) DOWN
(4, 0) LEFT
(2, 0) LEFT
1
(1, 3) DOWN
(1, 2) DOWN
(2, 3) DOWN
(2, 2) DOWN
(3, 3) DOWN
(3, 2) DOWN
(3, 1) LEFT
(2, 1) LEFT


题意:一个平面上有n个点的坐标,现在用一个球a去撞另外一个球b,b被撞到无穷远,a停在b的位置,问怎样撞可以使最后平面上的球最少。

思路:先用并查集将在同一行或者同一列上的球连成一个集合,用dfs搜索输出。

代码:


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 2005
#define MAXN 2000005
#define mod 1000000009
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define FRE(i,a,b)  for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b)  for(i = a; i < b; i++)
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define mem(t, v)   memset ((t) , v, sizeof(t))
#define sf(n)       scanf("%d", &n)
#define sff(a,b)    scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf          printf
#define DBG         pf("Hi\n")
typedef long long ll;
using namespace std;

struct Node
{
    int x,y;
}node[maxn];

struct Edge
{
    int u,v,next;
}edge[MAXN];

int head[maxn];
int father[maxn];
int num,n;
bool vis[maxn];

void init()
{
    num=0;
    mem(head,-1);
    for (int i=0;i<=n;i++)
    {
        father[i]=i;
        vis[i]=false;
    }
}

void addedge(int u,int v)
{
    edge[num]={u,v,head[u]};
    head[u]=num++;
    edge[num]={v,u,head[v]};
    head[v]=num++;
}

int find_father(int x)
{
    if (x!=father[x])
        father[x]=find_father(father[x]);
    return father[x];
}

void Union(int x,int y,int cnt)
{
    int i,j;
    for (i=0;i<cnt;i++)
    {
        int u=node[i].x,v=node[i].y;
        if (x==u||y==v)
        {
            addedge(i,cnt);
            int fu=find_father(i);
            int fv=find_father(cnt);
            if (fu!=fv) father[fu]=fv;
        }
    }
}

void print(int i,int j)
{
    printf("(%d, %d) ",node[i].x,node[i].y);
    if (node[i].x==node[j].x)
    {
        if (node[i].y<node[j].y)
            pf("UP\n");
        else
            pf("DOWN\n");
        return ;
    }
    if (node[i].x<node[j].x)
        pf("RIGHT\n");
    else
        pf("LEFT\n");
    return ;
}

void dfs(int u,int pre)
{
    vis[u]=true;
    for (int i=head[u];i+1;i=edge[i].next)
    {
        int v=edge[i].v;
        if (!vis[v])
            dfs(v,u);
    }
    if (pre!=-1)
        print(u,pre);
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("C:/Users/asus1/Desktop/IN.txt","r",stdin);
#endif
    int i,j,x,y;
    while (~sf(n))
    {
        init();
        for (i=0;i<n;i++)
        {
            sff(node[i].x,node[i].y);
            Union(node[i].x,node[i].y,i);
        }
        int ans=0;
        for (i=0;i<n;i++)
            if (father[i]==i) ans++;
        pf("%d\n",ans);
        for (i=0;i<n;i++)
            if (father[i]==i)
                dfs(i,-1);
    }
    return 0;
}



ZOJ 3761 —— Easy billiards(并查集+深搜)

题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3761 桌面上有N个球,每次可以使某个球向上,下,左,右四个方向运动,...
  • hongrock
  • hongrock
  • 2014年03月02日 18:41
  • 646

ZOJ 3761 Easy billiards(并查集+树遍历)

E - Easy billiards Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Su...
  • u010527492
  • u010527492
  • 2014年04月01日 10:33
  • 469

ZOJ 3761 —— Easy billiards(并查集+深搜)

题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3761桌面上有N个球,每次可以使某个球向上,下,左,右四个方向运动,但...
  • Davenny
  • Davenny
  • 2017年08月07日 14:01
  • 121

ZOJ3261并查集逆向处理

题意:       给你一些点,还有一些边,每个点上都有一个权值,然后有一些询问,分为两种, query a 询问与a直接或者间接想连的点中最大权值的是那个点,输出那个点,如果那个点的权值小于等于...
  • u013761036
  • u013761036
  • 2015年04月05日 15:34
  • 589

ZOJ - 3496 Assignment 上下界最大流+二分

题目链接点这里 毒瘤题,,wa了无数发,,,才发现当m==0的时候,,会输出一些奇怪的东西。。。 以后,,不管什么题都要记得特判,,恩,,,不然会死的很惨。。 #include #inc...
  • qq_30927651
  • qq_30927651
  • 2017年03月31日 23:04
  • 193

ZOJ2838【LCA在线查询】

模板题。 推荐博文:点我打开链接 博主再啰嗦几句: 储存遍历序列的数组ver[ ]; 每个结点第一次出现的位置的数组 First[ ]; 当前位置的深度的数组 deep[ ]   ...
  • KEYboarderQQ
  • KEYboarderQQ
  • 2017年04月08日 21:42
  • 433

九度OJ 题目1006:ZOJ问题

一.题目描述: 对给定的字符串(只包含'z','o','j'三种字符),判断他是否能AC。  是否AC的规则如下: 1. zoj能AC; 2. 若字符串形式为xzojx,则也能AC,其中x可...
  • lhyer
  • lhyer
  • 2015年08月07日 20:53
  • 902

浙大ZOJ 1009 Enigma问题解决及别人的解决方案

教训:在这题上浪费太多次机会了,因为以下几个原因: 1. 没考虑到m(m为轮子字母表的规模)为1的情况,从而导致出现“Floating Point Error”。通过将“if(i!=0&&i%(m-...
  • xiaogugood
  • xiaogugood
  • 2014年01月06日 17:16
  • 1653

POJ,ZOJ题目分类(多篇整合版,分类很细致,全面)

水题: 3299,2159,2739,1083,2262,1503,3006,2255,3094 初级: 一、基本算法:        (1)枚举 (1753,2965)  ...
  • dg357442101
  • dg357442101
  • 2016年03月13日 14:24
  • 3478

ZOJ 3496 二分+上下界网络流

二分+上下界网络流 #include #include #include using namespace std; const int maxn = 510; const int inf =...
  • c3568
  • c3568
  • 2013年10月25日 20:56
  • 1373
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Easy billiards (zoj 3761 并查集+DFS)
举报原因:
原因补充:

(最多只允许输入30个字)