波老师(teacher/1S/64M)

16 篇文章 0 订阅
11 篇文章 0 订阅

【题目描述】

波波老师是一个地理老师。有一天他上课的时候,他在地图上标记了N个点,第i个点在点(Xi,Yi)。他想知道,是否存在四个点(A,B,C,D)(A<B,C<D,AC或者BD),使AB之间的曼哈顿距离和CD之间的曼哈顿距离相等。

如果存在这样的四个点,输出YES,否则输出NO

 

【输入格式】

输入文件第一行是一个T(T50),表示有T组数据。

接下来有T组数据,每组数据第一行是两个整数N,M,表示点的个数以及点的坐标的边界,然后有N行,第i行有两个整数Xi,Yi表示第i个点的坐标(Xi,Yi)(0Xi,YiM)

 

【输出格式】

输出文件有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;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这段代码哪错了 #include <iostream> #include <iomanip> using namespace std; class Staff { protected: int code; string name; static int count; public: Staff(string n) { name = n; code = count; count++; } void SetName(string s) { name = s; } string GetName() { return name; } int GetCode() { return code; } static int GetStaffCount() { return count; } }; class Teacher : virtual public Staff { protected: string subject; public: Teacher(string n, string m) : Staff(n) { subject = m; } void SetSubject(string s) { subject = s; } string GetSubject() { return subject; } }; class Officer : virtual public Staff { protected: string work; public: Officer(string n, string m) : Staff(n) { work = m; } void SetWork(string s) { work = s; } string GetWork() { return work; } }; class Teacher_Officer : public Teacher, public Officer { public: Teacher_Officer(string n, string m, string s) : Staff(n), Teacher(n, m), Officer(n, s) {} }; int main() { Teacher t1("孔子", "儒家文学"); // 创建教学类员工t1 Teacher t2("公输班", "建筑学"); Officer o1("端木赐", "财务科长"); // 创建教辅类员工o1 Teacher_Officer to3("颜回", "儒家文学", "副院长"); // 创建教师教辅类员工to3 cout << "共有教职工" << Staff::GetStaffCount() << "人" << endl; cout << t1.GetCode() << ", " << t1.GetName() << ", " << t1.GetSubject() << endl; cout << t2.GetCode() << ", " << t2.GetName() << ", " << t2.GetSubject() << endl; cout << o1.GetCode() << ", " << o1.GetName() << ", " << o1.GetWork() << endl; cout << to3.GetCode() << ", " << to3.GetName() << ", " << to3.GetSubject() << ", " << to3.GetWork() << endl; return 0; }
最新发布
05-17
这段代码有两个问题: 1.需要将 `count` 初始化为 0,因为静态成员变量不会自动初始化为 0。 2.在 `Teacher_Officer` 类的构造函数中,应该只给 `Teacher` 和 `Officer` 传递它们自己的参数,而不是将 `Staff` 类的参数也传递进去。 修改后的代码如下: ``` #include <iostream> #include <iomanip> using namespace std; class Staff { protected: int code; string name; static int count; public: Staff(string n) { name = n; code = count; count++; } void SetName(string s) { name = s; } string GetName() { return name; } int GetCode() { return code; } static int GetStaffCount() { return count; } }; int Staff::count = 0; class Teacher : virtual public Staff { protected: string subject; public: Teacher(string n, string m) : Staff(n) { subject = m; } void SetSubject(string s) { subject = s; } string GetSubject() { return subject; } }; class Officer : virtual public Staff { protected: string work; public: Officer(string n, string m) : Staff(n) { work = m; } void SetWork(string s) { work = s; } string GetWork() { return work; } }; class Teacher_Officer : public Teacher, public Officer { public: Teacher_Officer(string n, string m, string s) : Teacher(n, m), Officer(n, s) {} }; int main() { Teacher t1("孔子", "儒家文学"); // 创建教学类员工t1 Teacher t2("公输班", "建筑学"); Officer o1("端木赐", "财务科长"); // 创建教辅类员工o1 Teacher_Officer to3("颜回", "儒家文学", "副院长"); // 创建教师教辅类员工to3 cout << "共有教职工" << Staff::GetStaffCount() << "人" << endl; cout << t1.GetCode() << ", " << t1.GetName() << ", " << t1.GetSubject() << endl; cout << t2.GetCode() << ", " << t2.GetName() << ", " << t2.GetSubject() << endl; cout << o1.GetCode() << ", " << o1.GetName() << ", " << o1.GetWork() << endl; cout << to3.GetCode() << ", " << to3.GetName() << ", " << to3.GetSubject() << ", " << to3.GetWork() << endl; return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值