1. 程式人生 > >【洛谷】P1227 [JSOI2008]完美的對稱

【洛谷】P1227 [JSOI2008]完美的對稱

post != sin 關於 一個 cmp ble 這樣的 包含

題目描述

在峰會期間,必須使用許多保鏢保衛參加會議的各國代表。代表們除了由他自己的隨身保鏢保護外,組委會還指派了一些其他的特工和阻擊手保護他們。為了使他們的工作卓有成效,使被保衛的人的安全盡可能得到保障,保鏢被分配到被保護人的各個方向。

保鏢的最佳站立位置應該是這樣的:被保護人應站在所有保鏢的對稱中心。但是,只要被保

護人一移動,保鏢就很難根據要人的新位置調整位置。大多數的特工都很難對此作出實時調整。

因此,安全部長決定將該過程逆轉一下,保鏢先站好自己的位置,然後要人在他們的對稱中心找到合適的位置。如果要人隨便走動,我們就對他的安全不必負責。

你的工作是使這個過程自動操作。給出一組N個點(保鏢的位置),你要找出它們的對稱中心S,在這兒被保護人將相對安全。下面以此類推。

首先我們給定一點A以及對稱中心S,點A‘是點A以S為對稱中心形成的像點,即點S是線段AA‘的對稱中心。

點陣組(X)以S為中心的像點是由每個點的像點組成的點陣組。X是用來產生對稱中心S的,即點陣X以S為中心的像點的集合即為點陣X本身。

技術分享圖片

輸入輸出格式

輸入格式:

輸入文件第一行是一個整數N,1<=N<=20000,接下來的N行每行包含用空格隔開的兩個整數Xi和Yi,-100000<=Xi,Yi<=100000,表示這組點陣中第I個點的笛卡爾坐標值。

因為任何兩個保鏢都不會站在同一個位置上,所以在給定的作業中,任何兩點都不相同。但註意保鏢可以站在被保護人相同的位置。

輸出格式:

輸出文件僅有一行。如果給定的點陣能產生一個對稱中心,則輸出“V.I.P. should stay at (x,y).”,其中X和Y代表中心的笛卡爾坐標值,格式為四舍五入保留至小數點後一位。

如果該組點陣無對稱中心,輸出"This is a dangerous situation!",註意輸出時除了兩個單詞之間用一個空格隔開外,不要輸出多余空格。

輸入輸出樣例

輸入樣例#1:

8
1 10
3 6
6 8
6 2
3 -4
1 0
-2 -2
-2 4

輸出樣例#1:

V.I.P. should stay at (2.0,3.0).

說明

[JSOI2008]第二輪

題解:

這道題大概是歷年JSOI省選中最簡單的一題,難度應該只有NOIP普及組T2~T3(應該不到T3的難度)。

我們發現:假設(a,b)是該圖的對稱中心,那麽設(x1,y1)、(x2,y2)關於這點成中心對稱(前提是存在這兩個點),顯然:a = (x1+x2)/2 ; b = (y1+y2)/2;

進而所有這樣成對的2個點都滿足這個式子,我們不妨把這個過程逆過來,即所有點的橫坐標的平均數即為對稱中心的橫坐標,所有點的縱坐標即為對稱中心的縱坐標。這樣就找到了對稱中心。

接著把所有點以x為第一關鍵字,y為第二關鍵字從小到大排序。接著檢驗 第i個點 和 第(n-i+1)個點 是否滿足上面的等式即可判斷數據是否合法。

Code:

#include<bits/stdc++.h>
using namespace std;

inline int read(){
	int f=1,x=0; char s=getchar();
	while(s<‘0‘ || s>‘9‘) {if(s==‘-‘)f=-1;s=getchar();}
	while(s>=‘0‘ && s<=‘9‘) {x = x*10+s-‘0‘;s=getchar();}
	return x*f;
}

struct node{
	int x,y;
	void Read()
	{
		x = read(); y = read();
	}
}a[20010];
int n; 

bool cmp(node a,node b)
{
	if (a.x == b.x) return a.y<b.y; else return a.x<b.x;
}

int main()
{
	scanf("%d",&n);
	long long sumx = 0 , sumy = 0;
	for (int i = 1 ; i <= n ; i++) {
		a[i].Read();
		sumx += a[i].x; sumy += a[i].y;
	}
	double xx = sumx*1.0/n , yy = sumy*1.0/n;
	int tx = floor(xx*2) , ty = floor(yy*2);
	bool f = 1;
	sort(a+1,a+1+n,cmp);
	for (int i = 1 ; i <= n/2; i ++)
		if (a[i].x+a[n-i+1].x != tx || a[i].y+a[n-i+1].y != ty) 
		{
			f = 0;
			break;
		}
	if (f == 1) printf("V.I.P. should stay at (%.1f,%.1f).\n",xx,yy);
	else printf("This is a dangerous situation!");
	return 0;
}

  

【洛谷】P1227 [JSOI2008]完美的對稱