波老师(teacher/1S/64M)
2016-08-07 11:11
309 查看
【题目描述】
波波老师是一个地理老师。有一天他上课的时候,他在地图上标记了N个点,第i个点在点(Xi,Yi)。他想知道,是否存在四个点(A,B,C,D)(A<B,C<D,A≠C或者B≠D),使AB之间的曼哈顿距离和CD之间的曼哈顿距离相等。
如果存在这样的四个点,输出YES,否则输出NO。
【输入格式】
输入文件第一行是一个T(T≤50),表示有T组数据。
接下来有T组数据,每组数据第一行是两个整数N,M,表示点的个数以及点的坐标的边界,然后有N行,第i行有两个整数Xi,Yi表示第i个点的坐标(Xi,Yi)(0
10226
≤Xi,Yi≤M)
【输出格式】
输出文件有T行,每一行为YES或者NO。
【输入】
2
3 10
1 1
2 2
3 3
4 10
8 8
2 3
3 3
4 4
【输出】
YES
NO
80%的数据,n<=1000,m<=100000
100的数据,n<=100000,m<=100000
===========================================================首先我们要知道,所谓的曼哈顿距离,其实就是dis(I,j)=|xi-xj|+|yi-yj|。Lpq神犇因为不知道曼哈顿距离而计算了直线距离,无奈爆零了。这题虽然数据规模n<=10^5,但却可以用暴力ac。究竟是为什么呢?仔细读题,我们可以从m的范围入手。因为m的范围最多只有10^5,那么曼哈顿距离最多只有2*10^5,可以用计数排序统计是否出现过。这样,我们就可以只枚举两个点,计算它们的曼哈顿距离并标记起来。如果发现当前两个点的曼哈顿距离已经被标记过,那么就可以直接输出yes并退出。但是显然有个问题,n<=10^5,枚举两个点可能会达到10^10的复杂度(不过实际上并没有达到这个复杂度)。假如没有任意两个点的曼哈顿距离相同,不是会TLE吗?然而,根据鸽巢原理可知,这n*(n-1)/2对点会产生n*(n-1)/2种曼哈顿距离,而且因为它大于2*10^5,所以一定会产生重复!在最坏情况下,前2*10^5种距离都互不相同,下一对点的距离就必定属于前面这些出现过的距离中的一种。因此,本算法的复杂度应该是min(n^2,2*10^5),不超时。这也正应了我们oiers最喜欢的那句话:暴力出奇迹。不过在考试的时候我并没有想这么多,只考虑能拿到80%的分,因此数组也只开了10^3,导致剩下两组数据RE了。数组开小了是非常白痴的错误,也十分的令人痛心。以后一定要杜绝这种错误。
另外,事实上,当n充分大时,必然会有满足题意条件的点对存在,这时可以不必枚举,直接输出yes。(但我不会证明)#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 1e5 + 9;
const int maxm = 1e5 + 9;
struct Tnode {
int X, Y;
Tnode() {
X = Y = 0;
}
} points[maxn];
int t;
bool f[maxm << 1]; //f[i]表示是否出现过一对点的曼哈顿距离为i
int main() {
ios::sync_with_stdio(false);
freopen("teacher.in", "r", stdin);
freopen("teacher.out" , "w", stdout);
cin >> t;
while(t--) {
memset(f, false , sizeof f);
int n, m;
cin >> n >> m;
for(int i = 0; i < n; i++)
cin >> points[i].X >> points[i].Y;
bool isok = false; //是否找到了四个点满足题意要求
for(int i = 0; i + 1 < n && !isok; i++) //枚举两个点
for(int j = i + 1; j < n && !isok; j++) {
int dis = abs(points[i].X - points[j].X) + abs(points[i].Y - points[j].Y);
//计算它们的曼哈顿距离
if(f[dis]) { //如果曾经出现过相同的
cout << "YES" << endl;
isok = true; //停止寻找
}
f[dis] = true; //标记这个距离出现过
}
if(!isok) cout << "NO" << endl; //找遍了也没有相同的
}
return 0;
}
波波老师是一个地理老师。有一天他上课的时候,他在地图上标记了N个点,第i个点在点(Xi,Yi)。他想知道,是否存在四个点(A,B,C,D)(A<B,C<D,A≠C或者B≠D),使AB之间的曼哈顿距离和CD之间的曼哈顿距离相等。
如果存在这样的四个点,输出YES,否则输出NO。
【输入格式】
输入文件第一行是一个T(T≤50),表示有T组数据。
接下来有T组数据,每组数据第一行是两个整数N,M,表示点的个数以及点的坐标的边界,然后有N行,第i行有两个整数Xi,Yi表示第i个点的坐标(Xi,Yi)(0
10226
≤Xi,Yi≤M)
【输出格式】
输出文件有T行,每一行为YES或者NO。
【输入】
2
3 10
1 1
2 2
3 3
4 10
8 8
2 3
3 3
4 4
【输出】
YES
NO
80%的数据,n<=1000,m<=100000
100的数据,n<=100000,m<=100000
===========================================================首先我们要知道,所谓的曼哈顿距离,其实就是dis(I,j)=|xi-xj|+|yi-yj|。Lpq神犇因为不知道曼哈顿距离而计算了直线距离,无奈爆零了。这题虽然数据规模n<=10^5,但却可以用暴力ac。究竟是为什么呢?仔细读题,我们可以从m的范围入手。因为m的范围最多只有10^5,那么曼哈顿距离最多只有2*10^5,可以用计数排序统计是否出现过。这样,我们就可以只枚举两个点,计算它们的曼哈顿距离并标记起来。如果发现当前两个点的曼哈顿距离已经被标记过,那么就可以直接输出yes并退出。但是显然有个问题,n<=10^5,枚举两个点可能会达到10^10的复杂度(不过实际上并没有达到这个复杂度)。假如没有任意两个点的曼哈顿距离相同,不是会TLE吗?然而,根据鸽巢原理可知,这n*(n-1)/2对点会产生n*(n-1)/2种曼哈顿距离,而且因为它大于2*10^5,所以一定会产生重复!在最坏情况下,前2*10^5种距离都互不相同,下一对点的距离就必定属于前面这些出现过的距离中的一种。因此,本算法的复杂度应该是min(n^2,2*10^5),不超时。这也正应了我们oiers最喜欢的那句话:暴力出奇迹。不过在考试的时候我并没有想这么多,只考虑能拿到80%的分,因此数组也只开了10^3,导致剩下两组数据RE了。数组开小了是非常白痴的错误,也十分的令人痛心。以后一定要杜绝这种错误。
另外,事实上,当n充分大时,必然会有满足题意条件的点对存在,这时可以不必枚举,直接输出yes。(但我不会证明)#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 1e5 + 9;
const int maxm = 1e5 + 9;
struct Tnode {
int X, Y;
Tnode() {
X = Y = 0;
}
} points[maxn];
int t;
bool f[maxm << 1]; //f[i]表示是否出现过一对点的曼哈顿距离为i
int main() {
ios::sync_with_stdio(false);
freopen("teacher.in", "r", stdin);
freopen("teacher.out" , "w", stdout);
cin >> t;
while(t--) {
memset(f, false , sizeof f);
int n, m;
cin >> n >> m;
for(int i = 0; i < n; i++)
cin >> points[i].X >> points[i].Y;
bool isok = false; //是否找到了四个点满足题意要求
for(int i = 0; i + 1 < n && !isok; i++) //枚举两个点
for(int j = i + 1; j < n && !isok; j++) {
int dis = abs(points[i].X - points[j].X) + abs(points[i].Y - points[j].Y);
//计算它们的曼哈顿距离
if(f[dis]) { //如果曾经出现过相同的
cout << "YES" << endl;
isok = true; //停止寻找
}
f[dis] = true; //标记这个距离出现过
}
if(!isok) cout << "NO" << endl; //找遍了也没有相同的
}
return 0;
}
相关文章推荐
- 音阶(ljestvica/1S/64M)
- NOIP2004火星人
- LAMP - Apache访问控制
- 【洛谷1211 [USACO1.3]牛式 Prime Cryptarithm】【枚举】
- 白书刷题记录
- 后台开发面试 linux os
- 2016 年大沥镇小学青少年信息学奥林匹克竞赛反思(甲乙组)
- 第三周小结+赛前最终总结(4.24~4.27)
- hdu 5781 ATM Mechine 概率(期望)dp
- STL之pair
- USACO 2016 JANUARY CONTEST, BRONZE PROBLEM 3. MOWING THE FIELD(收割庄稼)
- USACO 2016 JANUARY CONTEST, BRONZE PROBLEM 1. PROMOTION COUNTING
- gdoi2009中山市选T2 小球
- gdoi2009中山市选T1 谁能赢呢?
- usaco2016open gold3 248
- 进程同步之理发师问题
- usaco2016open gold2 closing
- usaco2016open gold1 split
- usaco2016open silver3 closing
- 集训第二周小结(4.17~4.23)