【推导】【凸包】MIPT-2016 Pre-Finals Workshop, Taiwan NTU Contest, Sunday, March 27, 2016 Problem D. Drawing Hell

平面上n个点,两个人交替决策,用线段连接两个点,但不能跨越其他点或者已经存在的线段。不能做的人算输,问你谁赢。

实际上,跟两个人的决策无关,n个点将平面三角剖分,只需要算出有几条边即可。

凸包上如果有K个点,那么图中那K-1条实边每条贡献一个三角形。

凸包内其他的边,每条贡献2个三角形。除了最中心那一个贡献一个。

假设总的三角形数是X,那么总的线段数就是(X*3+K)/2。

线段数是奇数就先手胜,否则后手胜。

#include<cstdio>
#include<algorithm>
using namespace std;
struct Point{
	int x,y;
	Point(const int &x,const int &y){
		this->x=x;
		this->y=y;
	}
	Point(){}
	void read(){
		scanf("%d%d",&x,&y);
	}
}p[1005],q[1005];
typedef Point Vector;
Vector operator - (const Point &a,const Point &b){
	return Vector(a.x-b.x,a.y-b.y);
}
int Cross(const Vector &a,const Vector &b){
	return a.x*b.y-a.y*b.x;
}
bool cmp(const Point &a,const Point &b){
	return a.x!=b.x ? a.x<b.x : a.y<b.y;
}
int n,K,T;
int main(){
//	freopen("d.in","r",stdin);
	scanf("%d",&T);
	for(;T;--T){
		K=0;
		scanf("%d",&n);
		for(int i=0;i<n;++i){
			p[i].read();
		}
		sort(p,p+n,cmp);
		bool flag=1;
		for(int i=1;i<n-1;++i){
			if(Cross(p[i+1]-p[i],p[i]-p[i-1])!=0){
				flag=0;
				break;
			}
		}
		if(flag){
			puts((n-1)%2==1 ? "T^T" : "OwO");
			continue;
		}
		for(int i=0;i<n;++i){
			while(K>1 && Cross(q[K-1]-q[K-2],p[i]-q[K-1])<0){
				--K;
			}
			q[K++]=p[i];
		}
		for(int i=n-2,t=K;i>=0;--i){
			while(K>t && Cross(q[K-1]-q[K-2],p[i]-q[K-1])<0){
				--K;
			}
			q[K++]=p[i];
		}
		--K;
		int A=K-1;
		int B=n-K-1;
		int sjxs=A+B*2+1;
		puts((sjxs*3+K)/2%2==1 ? "T^T" : "OwO");
	}
	return 0;
}
时间: 2024-11-05 18:43:59

【推导】【凸包】MIPT-2016 Pre-Finals Workshop, Taiwan NTU Contest, Sunday, March 27, 2016 Problem D. Drawing Hell的相关文章

【推导】【贪心】XVII Open Cup named after E.V. Pankratiev Stage 4: Grand Prix of SPb, Sunday, Octorber 9, 2016 Problem H. Path or Coloring

题意:给你一张简单无向图(但可能不连通),再给你一个K,让你求解任意一个问题:K染色或者输出一条K长路径. 直接贪心染色,对一个点染上其相邻的点的颜色集合之中,未出现过的最小的颜色. 如果染成就染成了.如果到某个点,发现染不成,则倒着按照颜色从大到小回去,则一定恰好可以找出一条K长度的路径. #include<cstdio> #include<cstring> using namespace std; int first[1005],next[20005],v[20005],e,c

2016中国大学生程序设计竞赛(长春)-重现赛 1010Ugly Problem 回文数 模拟

Ugly Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 0    Accepted Submission(s): 0Special Judge Problem Description Everyone hates ugly problems. You are given a positive integer. You m

【博弈论】【SG函数】【线段树】Petrozavodsk Summer Training Camp 2016 Day 9: AtCoder Japanese Problems Selection, Thursday, September 1, 2016 Problem H. Cups and Beans

一开始有n个杯子,每个杯子里有一些豆子,两个人轮流操作,每次只能将一个豆子移动到其所在杯子之前的某个杯子里,不过可以移动到的范围只有一段区间.问你是否先手必胜. 一个杯子里的豆子全都等价的,因为sg函数是异或起来的值,所以一个杯子里如果有偶数个豆子,就没有意义. 用sg(i)表示i杯子中的豆子的sg值,sg(i)就是其所能移动到的那段杯子的区间的sg值的mex(未出现的最小非负整数).可以用线段树去做.是经典问题. 由于每次看似是后缀询问,实则是全局询问,故而主席树完全是多余的. 回顾一下区间m

【推导】【构造】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem E. Space Tourists

给你n,K,问你要选出最少几个长度为2的K进制数,才能让所有的n位K进制数删除n-2个元素后,所剩余的长度为2的子序列至少有一个是你所选定的. 如果n>K,那么根据抽屉原理,对于所有n位K进制数,必然会至少有1个数字出现2次或以上,所以00,11,...,K-1 K-1这样的数对是必选的. 对于其他的情况下,我们需要让他构造不出来n位不含重复数字的K进制数. 于是可以把K个数尽可能平均地分成n-1组,每一组内部让他们选出任意两个数都不合法,于是只能组间互相拼,这样他只能构造出最多n-1位的K进制

【推导】【贪心】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem D. Clones and Treasures

给你一行房间,有的是隐身药水,有的是守卫,有的是金币. 你可以任选起点,向右走,每经过一个药水或金币就拿走,每经过一个守卫必须消耗1个药水,问你最多得几个金币. 药水看成左括号,守卫看成右括号, 就从每个位置贪心地向右走,如果在 r 遇到不匹配,则把下一次的左端点置成r+1,接着走. O(n)即可. 因为如果把左端点放在上次的l和r之间,要么会发生不匹配,要么答案无法比上次走的更优. 队友代码: #include <iostream> #include <cstdio> #incl

工作周记 - 第六周 (2016/06/27 - 2016/07/01)

1.搭建定时任务quartz 本来是打算把定时任务放入后台管理中,这样目前没问题,但是弱后期加入权限管理-shiro,那么肯定有冲突的,原因是最新版的shiro会使用quartz-1.6版本,而最新的quartz已经到了2.3 有人索性把quartz版本降到了1.6,这样就没问题,我想这样不好,2.3的新功能都用不到,1.6多多少少肯定会有一定bug,所以就另开了一个项目作为定时任务,虽然现阶段的任务量少,但是后期一定会多起来,比如定时报表,定时跑批等等 这样也省的把原来的任务再分离出来,这么做

【计算几何】【极角排序】【二分】Petrozavodsk Summer Training Camp 2016 Day 6: Warsaw U Contest, XVI Open Cup Onsite, Sunday, August 28, 2016 Problem J. Triangles

平面上给你n(不超过2000)个点,问你能构成多少个面积在[A,B]之间的Rt三角形. 枚举每个点作为直角顶点,对其他点极角排序,同方向的按长度排序,然后依次枚举每个向量,与其对应的另一条直角边是单调的,可以用一个pointer做出来,然后可以得出那些同方向的向量的区间(这个代码好像有点问题,可能会退化,最好确定了一个LL之后,对一个方向的不要重复算RR.这里如果也改成二分就比较好,复杂度不会退化).然后通过二分可以得到A使得面积在[A,B]间的有哪些(其实这个因为也是单调的,好像也没必要二分,

【找规律】【递归】XVII Open Cup named after E.V. Pankratiev Stage 4: Grand Prix of SPb, Sunday, Octorber 9, 2016 Problem F. Doubling

题意: 给你一个n,问你R(n)对应的字符串长度最小的是啥. dp打个表出来,f(i)表示i值对应的字符串的最小长度,发现f(1)=1,f(2)=2,其他的情况下,若是偶数,则恰好在其外面加一对中括号,然后中间填i/2最优,若是奇数,恰好在i-1前面加个1最优. 于是递归输出答案即可. #include<cstdio> #include<iostream> #include<string> using namespace std; string work(int x){

【枚举】XVII Open Cup named after E.V. Pankratiev Stage 4: Grand Prix of SPb, Sunday, Octorber 9, 2016 Problem D. Cutting Potatoes

题意:有n个土豆,每个有体积V(i),你可以将每个土豆等分为不超过K份,问你最大块和最小块比值最小为多少. 直接枚举切法,只有n*K种,然后保证其为最大块,去算其他块的切法,即让其他块切得尽可能大即可.O(n*n*K). #include<cstdio> #include<cstring> using namespace std; int n,K,a[105],ans1=150,ans2=1,x[105],ansx[105]; int main(){ // freopen(&quo