zoj 3761
很简单但很虐心的一道题;
我感觉自己的算法没错,但是老是过不了;= =
但是还是把代码贴出来;
我的方法,用并查集的方式做一课树,然后对树进行遍历;
有多少棵树就有多少个点剩余;
#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的更多相关文章
- ZOJ 3761 Easy billiards 月赛E DFS
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3761 题目大意:给定n个位置的小球,小球的运动方向只能是水平或者 ...
- ZOJ - 3761 Easy billiards 【并查集+DFS】
题目链接 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3761 题意 在一个桌面上,给出一些球 如果在A球的某个方向的前方 ...
- zoj 3761(并查集+搜索)
题意:在一个平面上,有若干个球,给出球的坐标,每次可以将一个球朝另一个球打过去(只有上下左右),碰到下一个球之后原先的球停下来,然后被撞的球朝这个方向移动,直到有一个球再也撞不到下一个球后,这个球飞出 ...
- HZNU Training 4 for Zhejiang Provincial Collegiate Programming Contest 2019
今日这场比赛我们准备的题比较全面,二分+数论+最短路+计算几何+dp+思维+签到题等.有较难的防AK题,也有简单的签到题.为大家准备了一份题解和AC代码. A - Meeting with Alien ...
- ZOJ People Counting
第十三届浙江省大学生程序设计竞赛 I 题, 一道模拟题. ZOJ 3944http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=394 ...
- ZOJ 3686 A Simple Tree Problem
A Simple Tree Problem Time Limit: 3 Seconds Memory Limit: 65536 KB Given a rooted tree, each no ...
- ZOJ Problem Set - 1394 Polar Explorer
这道题目还是简单的,但是自己WA了好几次,总结下: 1.对输入的总结,加上上次ZOJ Problem Set - 1334 Basically Speaking ac代码及总结这道题目的总结 题目要求 ...
- ZOJ Problem Set - 1392 The Hardest Problem Ever
放了一个长长的暑假,可能是这辈子最后一个这么长的暑假了吧,呵呵...今天来实验室了,先找了zoj上面简单的题目练练手直接贴代码了,不解释,就是一道简单的密文转换问题: #include <std ...
- ZOJ Problem Set - 1049 I Think I Need a Houseboat
这道题目说白了是一道平面几何的数学问题,重在理解题目的意思: 题目说,弗雷德想买地盖房养老,但是土地每年会被密西西比河淹掉一部分,而且经调查是以半圆形的方式淹没的,每年淹没50平方英里,以初始水岸线为 ...
随机推荐
- rownum与rowId
一.RowNum Rownum是oracle生成结果集时得到的一个伪列, 按照读出行的顺序, 第一条rownum=1, 第二条=2. 对于 Oracle 的 rownum 问题,很多资料都说不支持 ...
- 使用kdbg或nemiver调试ROS
Kdbg Kdbg是KDE环境下的一个gdb的前端GUI,使用起来比较友好,速度也很快,安装和使用请参考: http://www.kdbg.org/ 在UBUNTU下可以直接使用APT安装: sudo ...
- IIS启用SSL
安全套接字层 (SSL) 是一套提供身份验证.保密性和数据完整性的加密技术.SSL 最常用来在 Web 浏览器和 Web 服务器之间建立安全通信通道.它也可以在客户端应用程序和 Web 服务之间使用. ...
- linux下挂载iso镜像的方法
新建目录/mnt/cdrom 执行命令 mount /dev/cdrom /mnt/cdrom [root@ocdp1 cdrom]# mount /dev/cdrom /mnt/cdrom moun ...
- 转-----EasyCHM制作教程
希望以后自己的笔记能够整理成 chm 格式的文档 制作过CHM帮助文件的同志们可能都遇到过以下两个问题: 1.制作好的CHM文件图像.公式不显示. 2.制作好的CHM文件在自己电脑上能显示,在别人电脑 ...
- SQLite 入门教程(一)基本控制台(终端)命令
一.基本简介 SQLite 是一个自持的(self-contained).无服务器的.零配置的.事务型的关系型数据库引擎.因为他很小,所以也可以作为嵌入式数据库内建在你的应用程序中.SQLite 被应 ...
- jsp(一) : servlet基础
1.客户 servlet容器 servlet 2.实现接口 #1.接口:servlet : constrontor .init().service.destroy ...
- Java 三大主流框架概述
Struts.Hibernate和Spring是我们Java开发中的常用关键,他们分别针对不同的应用场景给出最合适的解决方案.但你是否知道,这些知名框架最初是怎样产生的? 我们知道,传统的Java W ...
- Java实战之02Hibernate-02映射、一级缓存、实体对象状态
五.映射基础 1.实体类采用javabean的编写规范 JavaBean编写规范: a.类一般是public的 b.有默认的构造方法 c.字段都是私有的 d.提供公有的getter和setter方法 ...
- Linux网络服务器epoll模型的socket通讯的实现(一)
准备写一个网络游戏的服务器的通讯模块,参考网上看到的一些代码,在linux下面实现一个多线程的epoll模型的socket通讯的代码,以下是第一部分多线程的切换代码: 1 #include <s ...