197 A
题意
给一张长为a,宽为b的桌子。设有无数张半径为r的圆形纸片。有两个人在桌子上放纸片,之前已放好的纸片不能挪动位置,纸片在放的时候不能相交但可以外切且不能超过桌子的边界,谁放不了谁就输了。问先放的人是否一定能赢,若是输出“First”,否则输出“Second”。所有数 (le 100) 。
Examples
Input
3
1 3
2 3
0 0
1 1
2 0
Output
1 3 2
Input
4
1 2
2 3
1 4
-1 -2
3 5
-3 3
2 0
Output
4 2 1 3
解
197 D
题意
去掉“多组测试数据”
Examples
Input
5 4
##.#
##S#
#..#
#.##
#..#
Output
Yes
Input
5 4
##.#
##S#
#..#
..#.
#.##
Output
No
解
如果出现一个点使得vis[x%n][y%m]==true&&!(x==x%n&&y==y%m)
,就Yes;否则No
197 E
题意
平面上有 (n) 个点,现在有一棵树,要求在平面上画出这棵树,边不能相交。保证有解。(1le nle 1500)
Examples
Input
3
1 3
2 3
0 0
1 1
2 0
Output
1 3 2
Input
4
1 2
2 3
1 4
-1 -2
3 5
-3 3
2 0
Output
4 2 1 3
解
在dfn序列上分治。
对于一段区间,选定根节点所在的点为这些点中最左端的点。(重要)
然后按极角将剩余点排序,“按需(子树大小)分配”给当前根节点的所有子节点。
极角排序方法:叉积<0
Code
#include<bits/stdc++.h>
#define maxn 1503
using namespace std;
struct edge{
int to,next;
}e[maxn<<1];
int head[maxn],cnte;
void add(int u,int v){
e[++cnte].to=v;
e[cnte].next=head[u];
head[u]=cnte;
}
int n,dfn[maxn],cntdfn,rig[maxn],ans[maxn];
struct point{
long long x,y;
int num;
point(){}
point(long long _x,long long _y,int _num=0):x(_x),y(_y),num(_num){}
point operator -(const point& pnt)const{return point(x-pnt.x,y-pnt.y,num);}
long long cross(const point& pnt)const{return x*pnt.y-y*pnt.x;}
bool operator <(const point& pnt)const{return cross(pnt)>0;}
}a[maxn];
bool cmp(const point& pnt1,const point& pnt2){
return pnt1.x==pnt2.x?pnt1.y>pnt2.y:pnt1.x<pnt2.x;
}
void init(int u,int last){
dfn[u]=++cntdfn;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==last)continue;
init(v,u);
}
rig[u]=cntdfn;
}
void dfs(int u,int last,int l,int r){
sort(a+l,a+r+1,cmp);
ans[a[l].num]=u;
for(int i=l+1;i<=r;i++)a[i]=a[i]-a[l];
sort(a+l+1,a+r+1);
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==last)continue;
dfs(v,u,dfn[v],rig[v]);
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
for(int i=1;i<=n;i++)scanf("%lld%lld",&a[i].x,&a[i].y),a[i].num=i;
init(1,0);
dfs(1,0,1,n);
for(int i=1;i<=n;i++)printf("%d ",ans[i]);
return 0;
}