题解 P1227 【[JSOI2008]完美的对称】
这道题的思考难度不大。
1.思路分析:
我们为什么要按x坐标或者y坐标排序呢?
考虑这些点的x坐标(y坐标)
根据中点坐标公式:对于∀点
若最小的
则
∵
所以最小的
∴这道题要排序(本蒟蒻对y坐标排序,对x坐标排序也一样)。
2.代码实现:
我们如何判断这些保镖都关于一个点对称呢?
我们可以先提前算出最小的
然后再依次配对,如果有一组配对得出的答案和提前算好的
如果程序到了最后没有出现矛盾,则成功了,根据题目要求输出(tx, ty) 就行辣。
关键的Code:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <iomanip>
using namespace std;
int n;
struct node {
int x, y;
} a[20200];
int cmp(node p,node q) { // 普通的结构体排序的cmp函数,当然在结构体里写重载运算符也珂以。
if(p.y == q.y) return p.x < q.x; // 也要判断y坐标相等的情况。
return p.y < q.y;
}
inline int read() { //快读,没啥话好说。
register int x = 0, f = 1;
char ch = getchar();
while (!isdigit(ch)) {
if (ch == '-') f = -1;
ch = getchar();
}
while (isdigit(ch)) {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
void init() { // 为了使主函数看起来更简便,则把主函数中的代码放到一个单独的函数里,方便检查。
int i, j;
double tx, ty, px, py;
cin >> n;
for(i = 1; i <= n; i++)
cin >> a[i].x >> a[i].y;
sort(a + 1, a + n + 1, cmp);// 对结构体进行y坐标排序。
tx=(a[1].x + a[n].x + (0.0))/2;
ty=(a[1].y + a[n].y + (0.0))/2; //注意整数除以2不一定是整数,int转double要和0.0一起操作。
for(i = 1,j = n;i <= j; i++,j--) { //类似于two-pointers.
px = (a[i].x + a[j].x + (0.0))/2;
py = (a[i].y + a[j].y + (0.0))/2;
if(px != tx || py != ty) {
printf("This is a dangerous situation!\n"); //此时已出现矛盾。
return;
}
}
cout<<"V.I.P. should stay at ("<<fixed<<setprecision(1)<<tx<<","<<fixed<<setprecision(1)<<ty<<")."<<endl; //没有出现矛盾,根据题目要求输出即可。
}
int main() {
init();//在主函数里调用。
return 0;
}