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

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

但是还是把代码贴出来;

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

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

#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. rownum与rowId

      一.RowNum Rownum是oracle生成结果集时得到的一个伪列, 按照读出行的顺序, 第一条rownum=1, 第二条=2. 对于 Oracle 的 rownum 问题,很多资料都说不支持 ...

  2. 虚拟机Linux系统中安装SYNOPSYS工具图解教程

                                        V TRON KO 2.8.2 启动 dv 在终端运行命令: lmli2 然后再运行命令: dv V TRON KO V TRO ...

  3. hdu 1096 A+B for Input-Output Practice (VIII)

    A+B for Input-Output Practice (VIII) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/3 ...

  4. git 配置用户名和邮箱

    在安装了git for windows之后,个人总是忘记配置git config的命令,以此记录一下: 配置用户名和邮箱的命令 git config --global user.name " ...

  5. activiti源码解读之心得整编

    TaskService.completeTask()的执行内幕是啥? activiti采取了command模式,completeTask会被包装成一个CompleteTaskCmd,一个Cmd执行的时 ...

  6. RabbitMQ 原文译04--路由

    在前一篇文章中我们构建了一个简单的日志系统,我们可以向多个接受者广播消息. 在这篇文章我,我们将要添加一些功能使得针对部分消息的接受成为可能,例如我们只对错误的消息进行磁盘记录,同时又可以把所有的消息 ...

  7. angularjs开发总结

    使用AngularJS有差不多一年时间了,前前后后也用了不少库和指令,整理了一下,分成四大类列出.有demo地址的,就直接连接到demo地址,其它的直接链到github托管库中. 图片视频类 angu ...

  8. SQL Server(高级) 关键字的使用 二

    二, 高级 关键字 -- 使用介绍 8,Top 的使用(Top子句返回记录的数目) select top number|percent column_name(s) from table_name 或 ...

  9. linux时间无法同步的解决方案

    问题描述: 在家里的ubuntu和windows上始终无法同步时间,也参考了很多资料还是不行.无意中的一次把笔记本拿到公司,发现可以同步时间,但是就觉得奇怪了.对比之后才发现是移动的网络没法连接ntp ...

  10. 第21条:理解Objective-C错误模型

    首先要注意的是: “自动引用计数”(Automatic Reference Counting, ARC,参见第30条)在默认情况下不是“异常安全的”(exception safe).具体来说,这意味着 ...