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

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

但是还是把代码贴出来;

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

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

#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. ASP.Net_入门准备

    基础篇:(学习能力取决于你的基础扎不扎实) 第一步 掌握一门.NET面向对象语言,C#或VB.NET 我强烈反对在没系统学过一门面向对象(OO)语言的前提下去学ASP.NET. ASP.NET是一个全 ...

  2. 20160505-hibernate入门2

    基本概念和CURD 开发流程 1由Domain object -> mapping->db.(官方推荐) 2由DB开始,用工具生成mapping和Domain object.(使用较多) ...

  3. 《JAVA核心技术卷 卷1 基础知识》

    第一卷 关键字:体系结构中立,可移植性,高性能,多线程 体系机构中立:通过解释字节码实现,优点是,让JAVA能在很多机器上运行.缺点是运行速度很慢. 可移植性:因为JAVA的基本数据类型有固定的大小. ...

  4. 浅谈JAVA集合框架(转载)_常用的Vector和HashMap

    原作者滴着:http://www.cnblogs.com/eflylab/archive/2007/01/20/625237.html Java提供了数种持有对象的方式,包括语言内置的Array,还有 ...

  5. SQLserver中常用的函数及实例

    聚合函数 as是可以起别名的,在select和from之间的是表示列名,可以不加单引号)(聚合函数中的count不仅能对数字进行操作还能对字符型进行操作,其余的只能对数字操作) 最小值 select  ...

  6. vim 高级使用技巧第二篇

    上篇我贴上了我使用的vim配置及插件配置,有这些东西只能是一个脚本堆积,无从谈高效的代码阅读开发. 下面我们就来写经常使用的命令,就从配置F系列快捷键开始吧. F+ n 快捷键配置 F1基本上时帮助, ...

  7. iOS创建UUID

    - (NSString *)getUUID { CFUUIDRef uuidObj = CFUUIDCreate(nil); //create a new UUID NSString * uuidSt ...

  8. iOS9开发之新增通知行为详解

    苹果在iOS8发布时,收到短信时可以直接在通知栏输入文字并回复,非常炫酷,然而这一功能并未真正开放给开发者.iOS9新增了用户通知行为UIUserNotificationActionBehaviorT ...

  9. artice与section的区别

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  10. UICollectionView的简单使用

    ChildModel.h #import <Foundation/Foundation.h> @interface ChildModel : NSObject @property (non ...