1. 程式人生 > 其它 >Node 中的 Stream ?應用場景?

Node 中的 Stream ?應用場景?

F. Nezzar and Nice Beatmap

題目描述

點此看題

解法一

根據餘弦定理,如果 \(|AB|\geq |AC|\) 時,\(\ang ABC<90\),也就是說從任何一個點開始,每次選離它距離最大的點作為下一個點一定可以滿足要求,時間複雜度 \(O(n^2)\)

解法二

調整法,更值得學習。

先隨便找一個排列,然後調整它。從後往前考慮(從前往後也一樣),如果當前三個點不成銳角,那麼交換後兩個點的位置就可以完成調整,因為這次調整可能影響到後面,遞迴的繼續調整後面的點即可,影響的兩個點都要遞迴,但是真正會進入遞迴的只有一個。

總結

合法解的構造可以考慮調整法,特別是小範圍的限制容易滿足的時候。

#include<bits/stdc++.h>
using namespace std;
# define ll long long
# define read read1<ll>()
# define Type template<typename T>
Type T read1(){
	T t=0;
	char k;
	bool vis=0;
	do (k=getchar())=='-'&&(vis=1);while('0'>k||k>'9');
	while('0'<=k&&k<='9')t=(t<<3)+(t<<1)+(k^'0'),k=getchar();
	return vis?-t:t;
}
# define fre(k) freopen(k".in","r",stdin);freopen(k".out","w",stdout)
# define eps 1e-7
struct A{
	double x,y;
	A(double _x=0,double _y=0){x=_x;y=_y;}
	bool vert(const A &b){return x*b.x+y*b.y==0;}
	bool obt(const A &b){return x*b.x+y*b.y<=eps;}
	A operator -(const A &b){return A(x-b.x,y-b.y);}
};
pair<A,int>a[5005];
int s;
void solve(int n){
	if(n+1>=s)return;
	while((a[n+1].first-a[n].first).obt(a[n+1].first-a[n+2].first))
		swap(a[n+1],a[n+2]),solve(n+1),solve(n+2);
}
int main(){
	s=read;
	for(int i=1;i<=s;++i)a[i]=make_pair(A(read,read),i);
	for(int n=s-2;n;--n)
		while((a[n+1].first-a[n].first).obt(a[n+1].first-a[n+2].first))
			swap(a[n+1],a[n+2]),solve(n+1),solve(n+2);
	for(int i=1;i<=s;++i)printf("%d ",a[i].second); 
	return 0;
}