很简单但很虐心的一道题;

我感觉自己的算法没错,但是老是过不了;= =

但是还是把代码贴出来;

我的方法,用并查集的方式做一课树,然后对树进行遍历;

有多少棵树就有多少个点剩余;

#include<cstdio>
#include<algorithm>
#include<cstring>
#define inf 1000000000
#define maxn 2009
using namespace std; struct node
{
int x;
int y;
int p;
int sum;
int son[];
bool operator <(const node &t)const
{
if(x==t.x)
return y<t.y;
else return x<t.x;
}
} no[maxn]; int f[maxn];
int find(int x)
{
return f[x]==x?x:f[x]=find(f[x]);
} int dis(int a,int b)
{
return(abs(no[a].x-no[b].x)+abs(no[a].y-no[b].y));
} bool check(int a,int b)
{
bool flag=;
if(no[a].x!=no[b].x&&no[a].y!=no[b].y)
flag=;
if(find(b)==a)flag=;
if(no[b].sum>=)flag=;
return flag;
} void dfs(int root)
{
for(int i=;i<no[root].sum;i++)
dfs(no[root].son[i]);
if(no[root].p!=-)
{
if(no[root].x==no[no[root].p].x)
{
if(no[root].y<no[no[root].p].y)
{
printf("(%d, %d) UP\n",no[root].x,no[root].y);
}
else printf("(%d, %d) DOWN\n",no[root].x,no[root].y);
}
else if(no[root].y==no[no[root].p].y)
{
if(no[root].x<no[no[root].p].x)
printf("(%d, %d) RIGHT\n",no[root].x,no[root].y);
else printf("(%d, %d) LEFT\n",no[root].x,no[root].y);
}
}
} int main()
{
int n;
int tar,d;
while(scanf("%d",&n)!=EOF)
{
for(int i=; i<n; i++)
{
scanf("%d%d",&no[i].x,&no[i].y);
no[i].p=-;
f[i]=i;
no[i].sum=;
}
for(int i=; i<n; i++)
{
d=inf;
tar=-;
for(int j=; j<n;j++)
{
if(i==j) continue;
if(dis(i,j)<d&&check(i,j))
{
d=dis(i,j);
tar=j;
}
}
if(tar==-){no[i].p=-;continue;}
no[i].p=tar;
f[i]=tar;
no[tar].son[no[tar].sum++]=i;
}
int ans=;
for(int i=; i<n; i++)
if(no[i].p==-)
ans++;
printf("%d\n",ans);
for(int i=; i<n; i++)
{
if(no[i].p==-)
dfs(i);
}
}
return ;
}
/*
18
1 1
2 1
2 2
4 2
5 2
6 2
2 3
3 3
4 3
5 3
7 3
5 4
8 4
1 5
2 5
3 5
4 5
5 5
*/

感谢文蔚大叔给我出了一组数据,让我意识到自己的算法的缺陷;

我先前的做法是构造一棵树,但是发现用贪心的方法建树的时候可能会把本来的一棵树变成两棵树,这样的话就错了;

所以我后来改成一个图,然后再图中dfs,这样的话就没错了;

#include<cstdio>
#include<cstring>
#define maxn 2009
#include<algorithm>
#define inf 1e9
using namespace std;
char s[][]={"LEFT","DOWN","RIGHT","UP"};
struct node
{
int x,y;
int son[];
int d[];
} no[maxn];
bool vis[maxn];
int f[maxn]; int check(int a,int b)
{
return (abs(no[a].x-no[b].x)+abs(no[a].y-no[b].y));
} int find(int x)
{
return f[x]==x?x:f[x]=find(f[x]);
} void un(int x,int y)
{
int a=find(x);
int b=find(y);
if(a!=b)
f[a]=b;
return;
} void dfs(int x,int f)
{
vis[x]=;
for(int i=;i<;i++)
{
int v=no[x].son[i];
if(v!=-&&!vis[v])
{
dfs(v,x);
}
}
if(f!=-)
{
for(int i=;i<;i++)
{
if(no[f].son[i]==x)
{
printf("(%d, %d) %s\n",no[x].x,no[x].y,s[i]);
}
}
}
} int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=; i<n; i++)
{
scanf("%d%d",&no[i].x,&no[i].y);
for(int j=; j<; j++)
{
no[i].son[j]=-;
no[i].d[j]=inf;
f[i]=i;
}
}
for(int i=; i<n; i++)
{
for(int j=; j<n; j++)
{
if(i==j)continue;
if(no[i].x==no[j].x)
{
un(i,j);
if(no[j].y<no[i].y)
{
if(check(i,j)<no[i].d[])
{
no[i].son[]=j;
no[i].d[]=check(i,j);
}
}
else
{
if(check(i,j)<no[i].d[])
{
no[i].son[]=j;
no[i].d[]=check(i,j);
}
}
}
else if(no[i].y==no[j].y)
{
un(i,j);
if(no[j].x<no[i].x)
{
if(check(i,j)<no[i].d[])
{
no[i].son[]=j;
no[i].d[]=check(i,j);
}
}
else
{
if(check(i,j)<no[i].d[])
{
no[i].son[]=j;
no[i].d[]=check(i,j);
}
}
}
}
}
int ans=;
for(int i=;i<n;i++)
{
if(f[i]==i)
ans++;
}
printf("%d\n",ans);
memset(vis,,sizeof vis);
for(int i=;i<n;i++)
{
dfs(i,-);
}
}
return ;
}

zoj 3761的更多相关文章

  1. ZOJ 3761 Easy billiards 月赛E DFS

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3761 题目大意:给定n个位置的小球,小球的运动方向只能是水平或者 ...

  2. ZOJ - 3761 Easy billiards 【并查集+DFS】

    题目链接 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3761 题意 在一个桌面上,给出一些球 如果在A球的某个方向的前方 ...

  3. zoj 3761(并查集+搜索)

    题意:在一个平面上,有若干个球,给出球的坐标,每次可以将一个球朝另一个球打过去(只有上下左右),碰到下一个球之后原先的球停下来,然后被撞的球朝这个方向移动,直到有一个球再也撞不到下一个球后,这个球飞出 ...

  4. HZNU Training 4 for Zhejiang Provincial Collegiate Programming Contest 2019

    今日这场比赛我们准备的题比较全面,二分+数论+最短路+计算几何+dp+思维+签到题等.有较难的防AK题,也有简单的签到题.为大家准备了一份题解和AC代码. A - Meeting with Alien ...

  5. ZOJ People Counting

    第十三届浙江省大学生程序设计竞赛 I 题, 一道模拟题. ZOJ  3944http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=394 ...

  6. ZOJ 3686 A Simple Tree Problem

    A Simple Tree Problem Time Limit: 3 Seconds      Memory Limit: 65536 KB Given a rooted tree, each no ...

  7. ZOJ Problem Set - 1394 Polar Explorer

    这道题目还是简单的,但是自己WA了好几次,总结下: 1.对输入的总结,加上上次ZOJ Problem Set - 1334 Basically Speaking ac代码及总结这道题目的总结 题目要求 ...

  8. ZOJ Problem Set - 1392 The Hardest Problem Ever

    放了一个长长的暑假,可能是这辈子最后一个这么长的暑假了吧,呵呵...今天来实验室了,先找了zoj上面简单的题目练练手直接贴代码了,不解释,就是一道简单的密文转换问题: #include <std ...

  9. ZOJ Problem Set - 1049 I Think I Need a Houseboat

    这道题目说白了是一道平面几何的数学问题,重在理解题目的意思: 题目说,弗雷德想买地盖房养老,但是土地每年会被密西西比河淹掉一部分,而且经调查是以半圆形的方式淹没的,每年淹没50平方英里,以初始水岸线为 ...

随机推荐

  1. Greedy

    在现实世界中,有这样一类问题:它有n个输入,而它的解就由这n个输入的某个子集组成,不过这个子集必须满足某些事先给定的条件.把那些必须满足的条件称为约束条件:而把满足约束条件的子集称为该问题的可行解.问 ...

  2. RMI原理

    一.分布式对象 在学习 RMI 之前,先来分布式对象(Distributed Object):分布式对象是指一个对象可以被远程系统所调用.对于 Java 而言,即对象不仅可以被同一虚拟机中的其他客户程 ...

  3. map 树木品种

    树木品种 TimeLimit: 1 Second   MemoryLimit: 32 Megabyte Totalsubmit: 517   Accepted: 120 Description 硬木是 ...

  4. android之模拟器访问外网设置

    一.确定adb可用 1.1 确认adb环境变量 1.2 命令行cmd 执行adb shell启动模拟器的命令行 二.DNS确认 2.1 确定DNS是否为电脑的DNS 2.2 修改DNS地址 三.效果图

  5. 议:如何将树形菜单形式的数据转化成HTML的二维表(相同内容需合并单元格)

    一般做OA类管理系统,经常涉及到“组织架构”的概念,那么像这种有上下层级关系的数据一般会做成树形菜单的方式显示,底层代码必定会用到递归算法.这篇随笔的目的就是要谈谈除了用树形菜单来显示这种上下层级关系 ...

  6. git subtree

    语法:git subtree split -P <被裁减的目录> -b <分支> git subtree split -P SDK/CustomUI(需要裁减的) -b Cus ...

  7. Android之Http网络编程(四)

    前面几篇博文简单的介绍了一些常见的Http的操作,这些操作几乎都是在新开的线程中进行的网络请求,并在日志中打印出获取到的网络数据.那么,问题来了!(呃~感觉下一句是蓝翔有木有?)如何在把获取到的网络数 ...

  8. pdf压缩之GSview

    今天实验室一个同学在网上投简历,网站要求投稿的简历pdf文件必须在100K以内.简历用的是ModernCV的模板,无论如何设置都在160k左右. 尝试用acrobat的压缩功能,也不能保证在100K以 ...

  9. Mysql主从配置+读写分离

    Mysql主从配置+读写分离     MySQL从5.5版本开始,通过./configure进行编译配置方式已经被取消,取而代之的是cmake工具.因此,我们首先要在系统中源码编译安装cmake工具. ...

  10. html-----017

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...