2012xs

所有表明可能包含多个测试样例的题目,请使用EOF判断输入是否完成。

例子:

C风格:(scanf(输入内容) != EOF)

C++风格:while (cin>>一些东西)

难度:
A.1数据结构,栈(poj1363)
B.1杂题
C.2构建全图/找出通路/搞成星状图也行(图论,杂题)
D.2DP(poj1745)
E.2线段树/扫描线(poj1177)
F.2bfs(poj2251)
G.1杂题
H.3凸包(poj1113)

A. Valid Pop Sequence

Description

In computer science, a stack is a last in, first out (LIFO) abstract data type and linear data structure. A stack can have any abstract data type as an element, but is characterized by two fundamental operations, called push and pop. The push operation adds a new item to the top of the stack.

Assume k integers is pushing into a stack in increasing order 1, 2, …, k. Please write a program that decides whether it is a valid pop sequence. For example, pushing 1, 2, 3 into a stack, (1, 2, 3) and (3, 2, 1) is a valid pop sequence, but (3, 1, 2) isn’t.

Input

The input consists of several test cases.

For each test case, one integer k (1 <= k <= 100000) is given in the first line.

Second line contains k integers, presenting a pop sequence.

Output

If the pop sequence is valid, print a line containsMy Dearest. Otherwise it containsThe Everlasting Guilty Crown

Sample Input

3

1 2 3

3

3 1 2

Sample Output

My Dearest

The Everlasting Guilty Crown

数组模拟栈!

 

#include <stdio.h>

int main()
{
	int k;
	while (scanf("%d", &k) != EOF)
	{
		int ar[100005], up = 0;
		int *top = ar;//前面ar[0]记录每次输入的数;
		bool flag = true;
		for (int i = 0; i < k; ++i)
		{
			scanf("%d", ar);
			if (!flag)
				continue;//不合要求的跳过;
			while (*ar > up)
				*(++top) = ++up;//入栈,通过up自加模拟;
			if (*ar == *top)
				--top;//出栈;
			else
				flag = false;
		}
		if (flag)
			printf("My Dearest\n");
		else
			printf("The Everlasting Guilty Crown\n");
	}
	return 0;
}


 

B.  变种斐波那契数列

问题描述

斐波那契数列的定义为

现在我们定义

输入

输入可能包含多个测试样例。

每行包含一个数n (1 <= n <= 1000)

输出

每一行包含一个数G(x),计算结果保留3位小数。

样例输入

1

2

3

4

10

样例输出

1.000

3.000

4.500

6.167

15.862

 

#include <stdio.h>

int main()
{
	int n;
	while (scanf("%d", &n) != EOF)
	{
		double a = 1, b = 1, res = 0;
		while (n--)
		{
			res += a / b;
			a = a + b;
			b = a - b;
		}
		printf("%.3lf\n", res);
	}
	return 0;
}

 

方法二:

想到先将式子变形 an=a[i]/a[i-1]=(a[i-1]+a[i-2])/a[i-1]=1+1/a(n-1)
 sn+=an,这个复杂度可以达到10^9,而上面那个只能到1000;

#include<stdio.h>
int main()
{
	int n;
	while(scanf("%d",&n)){
		double s=1.0,a=1.0;
		for(int i=1;i<n;i++){
			a=1.0+1.0/a;
			s+=a;
		}
		printf("%.3lf\n",s);
	}
	return 0;
}

 

C.   货币战争

问题描述

德国处于欧洲东西部之间的连接点,特别是柏林更是位于欧洲地理中心和交通枢纽的位置上。南来北往东行西去的客商都云集柏林,形成了欧洲的各种货币都在柏林集散的局面。从罗马帝国开始,柏林就是货币兑换中心,到拿破仑占据这一地区之后,对货币兑换的需求变得更加旺盛。

老布雷施劳德叫塞米欧(Samuel),他经营的主要业务是买卖当地政府的债券,在买卖的交易过程中赚取差价。当时这种债券发行的主要目的是为了抚恤在战争中失去丈夫或者儿子的家庭。1828年前后,布雷施劳德家族开始跟罗斯柴尔德家族建立起商业合作关系。由于罗斯柴尔德家族处于欧洲金融权力的顶峰,正是这样一种“搭上大腕”的商业合作关系,使得布雷施劳德家族一举从众多的柏林银行家中脱颖而出。1830年以后,布雷施劳德家族开始定期从罗斯柴尔德家族领取佣金,而当时柏林声名显赫的门德尔松这种老牌银行家族就逐渐被边缘化了。

布雷施劳德在罗氏家族的统一指挥协调下,在伦敦、巴黎、法兰克福、柏林、维也纳和那不勒斯的金融市场之间寻找低买高卖的套利机会。由于欧洲市场上各种债券和货币的价格在各个城市之间会略有不同,利用地域差价实现套利的关键是获取准确的情报和抓住恰当的时机。金融业从一开始就对情报有着非常高的要求,实际上现代国际情报机构就是建立在早期国际银行家族商业情报传递系统基础之上的。当时最先进的情报系统毫无疑问当属罗斯柴尔德家族的情报速递系统,其覆盖面、快捷性、保密性、准确率和复杂程度,都远远超过了各国政府官方的系统。

——宋鸿兵《货币战争2·金权天下》

这种在单纯在货币上买低卖高的策略,在信息技术还不发达的年代还有用。但是现在货币交易都已经全球联网,基本上全球价格一致。要买低卖高就需要对货币价格走势的预测和分析,这种分析不单单是快速的信息渠道就能实现的。

我们都知道,美元作为世界结算货币为货币兑换提供了很多方便。但是,考虑一下如果没有世界结算货币,这货币兑换该怎么进行呢?

输入

输入可能包含多个测试样例。

每个样例第1行包含两个数n m (2 <= n <= 1000, 1 <= m <= 2000)

接下来n行格式为

1 X = k Y

表明1单位货币 X可以兑换成k单位货物Y (0 <= X, Y < 100, 0 < k < 100, k为实数)

接下来m行格式为

a X = ? Y

表示请求计算a单位货币X可以兑换成多少单位货物Y (0 <= X, Y, a <= 100, a为正整数)

输出

对于每一个计算请求输出1行,若能兑换,输出格式为

a X = k Y

表示兑换结果,结果保留两位小数。

若不能兑换,则输出OMG

样例输入

3 4

1 0 = 18.207114152500 1

1 1 = 0.627187506368 2

1 3 = 0.514944196405 4

5 0 = ? 2

5 0 = ? 4

5 0 = ? 0

5 30 = ? 31

样例输出

5 0 = 57.10 2

OMG

5 0 = 5.00 0

OMG

提示

为避免积累误差,建议先计算1单位X能换多少单位Y,再乘以a得出结果。

简单的BFS啊!!~~只是难想到要用BFS做;

例如:输入[2,0][3,1][2,1][2,4]

[2]——[0]

|      \

[4]        [1]——[3]

t[] 0 1 4 3

    0 1 2 3

ts,te代表前后指针,一个个结点历搜;

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

double map[105][105];

void bfs(int s, int e)
{
	if (map[s][e] != 0)
		return;

	int t[105], ts, te;
	memset(t, 0, sizeof(t));
	ts = te = 0;

	for (int i = 0; i < 100; ++i)
		if (s != i && map[s][i] != 0)
			t[te++] = i;//记录初始结点;

	while (ts < te)
	{
		for (int i = 0; i < 100; ++i)
			if (map[s][i] == 0 && map[t[ts]][i] != 0 && t[ts] != i)//没标记过&&下一结点可以扩展&&未指向自己;
			{
				map[s][i] = map[s][t[ts]] * map[t[ts]][i];
				map[i][s] = 1 / map[s][i];
				t[te++] = i;//将结点记入队列,即扩展结点;
			}
		++ts;//指向下一结点;
	}
}

int main()
{
	int n, m;
	while (scanf("%d %d", &n, &m) != EOF)
	{
		memset(map, 0, sizeof(map));
		for (int i = 0; i < 100; ++i)
			map[i][i] = 1;

		for (int i = 0; i < n; ++i)
		{
			int X, Y, xx;
			double v;
			scanf("%d %d = %lf %d", &xx, &X, &v, &Y);
			map[X][Y] = v;
			map[Y][X] = 1 / v;
		}

		while (m--)
		{
			int X, Y, v;
			scanf("%d %d = ? %d", &v, &X, &Y);
			bfs(X, Y);
			if (map[X][Y] > 0)
				printf("%d %d = %.2lf %d\n", v, X, map[X][Y] * v, Y);
			else
				printf("OMG\n");
		}
	}
	return 0;
}


 

D. Divisibility

Description

Consider an arbitrary sequence of integers. One can place + or - operators between integers in the sequence, thus deriving different arithmetical expressions that evaluate to different values. Let us, for example, take the sequence: 17, 5, -21, 15. There are eight possible expressions:

17 + 5 + -21 + 15 = 16

17 + 5 + -21 - 15 = -14

17 + 5 - -21 + 15 = 58

17 + 5 - -21 - 15 = 28

17 - 5 + -21 + 15 = 6

17 - 5 + -21 - 15 = -24

17 - 5 - -21 + 15 = 48

17 - 5 - -21 - 15 = 18

We call the sequence of integers divisible by K if + or - operators can be placed between integers in the sequence in such way that resulting value is divisible by K. In the above example, the sequence is divisible by 7 (17+5+-21-15=-14) but is not divisible by 5.

You are to write a program that will determine divisibility of sequence of integers.

Input

The input consists of several test cases.

The first line of the input file contains two integers, N and K (1 <= N <= 10000, 2 <= K <= 100) separated by a space.

The second line contains a sequence of N integers separated by spaces. Each integer is not greater than 10000 by its absolute value.

Output

Write to the output file the word "Divisible" if given sequence of integers is divisible by K or "Not divisible" if it's not.

Sample Input

4 7

17 5 -21 15

Sample Output

Divisible

动态规划题!

 

/*dp[i][j]代表前i个数%k能否得到余数j。
若dp[n-1][0]=1,则合格;
数组的下表不能为负,可以+k)%k来置正;
*/

#include <stdio.h>
#include <string.h>

int N, K, ar[10005];
bool dp[10005][102];

int cn(int p)
{
	while (p < 0)
		p += K;
	return p % K;
}

int main()
{
	while (scanf("%d %d", &N, &K) != EOF)
	{
		memset(dp, 0, sizeof(dp));
		for (int i = 0; i < N; ++i)
		{
			scanf("%d", &ar[i]);
			ar[i] = cn(ar[i]);
		}

		dp[0][ar[0]] = true;
		for (int i = 1; i < N; ++i)
			for (int j = 0; j < K; ++j)
				dp[i][j] = dp[i - 1][cn(j + ar[i])] || dp[i - 1][cn(j - ar[i])];

		if (dp[N - 1][0])
			printf("Divisible\n");
		else
			printf("Not divisible\n");
	}
	return 0;
}



 

E.   城管的烦恼

问题描述

给我三千城管,我能征服世界。

虽然强悍如城管,也有他们自己的烦恼。城管烦恼之一就是无处不在的狗皮膏药。各位亲爱的小贩们这里贴一张老军医,那里贴一张办证,搞得我们的城管们烦不胜烦。但是市容毕竟是城管们的责任,你贴了人家就得给他撕掉。

这天城管大哥看到一面快被狗皮膏药贴满了的墙,经过一番辛苦之后,城管大哥终于把墙清理干净了。清理之后城管大哥想知道自己到底清理了多少墙面,好向上面要工钱,可是纸都给撕下来了,完全没法算。于是城管大哥调出监视录像,看着小贩们一边往上贴纸一边咬牙切齿。

输入

输入可能包含多个测试样例。

每个样例第1行包含一个数n (0 <= n < 5000)

接下来n行包含4个数,x1 y1 x2 y2 (-10000 <= x1, y1, x2, y2 <= 10000),表示一个小贩的广告把左上角点(x1, y1)到右下角点(x2, y2)的墙面盖住了。

输出

每个样例输出被覆盖的墙面面积。

样例输入

7

-15 10 5 0

-5 25 20 8

15 14 24 -4

0 4 16 -6

2 22 10 15

30 20 36 10

34 16 40 0

样例输出

1013

提示

如果同一块墙面被多次覆盖,面积也只算一次。

样例输入形成的图如上。

 

 

#include <stdio.h>
#include <string.h>

void _swap(int &a, int &b)
{
	a ^= b;
	b ^= a;
	a ^= b;
}

struct Point
{
	int x, y;
	Point(int x = 0, int y = 0)
		: x(x), y(y)
	{ }
};
bool operator==(const Point &l, const Point &r)
{
	return l.x == r.x && l.y == r.y;
}

struct Rect
{
	int l, t, r, b;
	Rect(const Point < = Point(), const Point &rb = Point())
		: l(lt.x), t(lt.y)
		, r(rb.x), b(rb.y)
	{
		if (l > r)
			_swap(l, r);
		if (t < b)
			_swap(t, b);
	}
	int area() const
	{
		return (r - l) * (t - b);
	}
	Point lt() const
	{
		return Point(l, t);
	}

	Point rt() const
	{
		return Point(r, t);
	}
	Point rb() const
	{
		return Point(r, b);
	}
	Point lb() const
	{
		return Point(l, b);
	}
};
bool operator==(const Rect &l, const Rect &r)
{
	return l.l == r.l && l.t == r.t && l.r == r.r && l.b == r.b;
}

struct Board
{
	Board *q;
	Rect rc;
	bool marked;
	Board(const Rect &trc = Rect(), bool bMarked = false)
		: q(NULL)
		, marked(bMarked)
	{
		setRect(trc);
	}
	void setRect(const Rect &value)
	{
		rc = value;
		marked = !rc.area();
	}
	~Board()
	{
		if (q)
			delete[] q;
	}
};

int paste(const Rect &rc, Board &b)
{
	if (b.marked)
		return 0;

	Point mid((b.rc.l + b.rc.r) / 2, (b.rc.t + b.rc.b) / 2);

	if (!b.q)
	{
		if (b.rc == rc)
		{
			b.marked = true;
			return rc.area();
		}
		else
		{
			b.q = new Board[4];
			b.q[0].setRect(Rect(mid, b.rc.lt()));
			b.q[1].setRect(Rect(mid, b.rc.rt()));
			b.q[2].setRect(Rect(mid, b.rc.rb()));
			b.q[3].setRect(Rect(mid, b.rc.lb()));
		}
	}

	int ret = 0;

	if (rc.t > mid.y)
	{
		if (rc.l < mid.x)
		{
			int r = rc.r < mid.x ? rc.r : mid.x;
			int bn = rc.b > mid.y ? rc.b : mid.y;
			ret += paste(Rect(rc.lt(), Point(r, bn)), b.q[0]);
		}

		if (rc.r > mid.x)
		{
			int l = rc.l > mid.x ? rc.l : mid.x;
			int bn = rc.b > mid.y ? rc.b : mid.y;
			ret += paste(Rect(rc.rt(), Point(l, bn)), b.q[1]);
		}
	}

	if (rc.b < mid.y)
	{
		if (rc.r > mid.x)
		{
			int l = rc.l > mid.x ? rc.l : mid.x;
			int t = rc.t < mid.y ? rc.t : mid.y;
			ret += paste(Rect(rc.rb(), Point(l, t)), b.q[2]);
		}
		if (rc.l < mid.x)
		{
			int r = rc.r < mid.x ? rc.r : mid.x;
			int t = rc.t < mid.y ? rc.t : mid.y;
			ret += paste(Rect(rc.lb(), Point(r, t)), b.q[3]);
		}
	}

	bool flag = true;
	for (int i = 0; flag && i < 4; ++i)
		flag = b.q[i].marked;

	if (flag)
	{
		delete[] b.q;
		b.q = NULL;
		b.marked = true;
	}

	return ret;
}

int main()
{
	int n;
	while (scanf("%d", &n) != EOF)
	{
		int ret = 0;
		Board b(Rect(Point(-10002, 10002), Point(10002, -10002)));
		while (n--)
		{
			Rect rc;
			scanf("%d %d %d %d", &rc.l, &rc.t, &rc.r, &rc.b);

			ret += paste(rc, b);
		}
		printf("%d\n", ret);
	}
	return 0;
}


 

F.    Guilty Crown

问题描述

樱满集(写作集念作锈)是个拥有王之力量的男人,为了阻止恙神涯引发第3次失落的圣诞节并救出祈,果断侵入御台场的24区。这座复杂的建筑物里有各种各样的通道,房间,死路之类的东西。

在行动之前,集拜托鸫找出一条离祈最近的路,告诉集要最快多久才能找到祈。

输入

输入可能包含多个测试样例。

第一行包含两个数R L C (1 <= R, L, C <= 30)

接下来是RL*C的矩阵(LC列)。

#表示房间,不可通行

.表示道路,可以通行

S表示集开始位置

E表示祈的所在位置

输出

若集可以到达祈的地方,输出一行包含一个数字k,表示集到祈的最短距离;否则输出一行包含字符串Sota!!

样例输入

3 4 5

S....

.###.

.##..

###.#

 

#####

#####

##.##

##...

 

#####

#####

#.###

####E

 

1 3 3

S##

#E#

###

样例输出

11

Sota!!

就是多了一个高度变成了立体的,简单的BFS题啊! 用结构体加队列想法挺不错的!

 

#include <stdio.h>
#include <string.h>
#include <queue>

using std::queue;

struct StepNode
{
	int a, b, c, step;
};

const int dir[][3] = {{0, -1, 0}, {-1, 0, 0}, {0, 1, 0}, {1, 0, 0}, {0, 0, 1}, {0, 0, -1}};

char map[35][35][35];

int bfs(StepNode no)
{
	queue<StepNode> qu;
	qu.push(no);

	while (!qu.empty())
	{
		no = qu.front();
		qu.pop();

		for (int i = 0; i < 6; ++i)
		{
			StepNode n = no;

			n.a += dir[i][0];
			n.b += dir[i][1];
			n.c += dir[i][2];
			++n.step;
			if (map[n.a][n.b][n.c] == '.')
			{
				qu.push(n);
				map[n.a][n.b][n.c] = '#';
			}
			else if (map[n.a][n.b][n.c] == 'E')
				return n.step;
		}
	}

	return 0;
}

int main()
{
	int L, R, C;
	while (scanf("%d %d %d", &L, &R, &C) != EOF && L)
	{
		memset(map, '#', sizeof(map));
		StepNode s;
		s.a = s.b = s.c = s.step = 0;
		for (int a = 1; a <= L; ++a)
			for (int b = 1; b <= R; ++b)
			{
				scanf("%s", &map[a][b][1]);
				for (int c = 1; !s.a && c <= C; ++c)
					if (map[a][b][c] == 'S')
					{
						s.a = a;
						s.b = b;
						s.c = c;
					}
			}
		int ret = bfs(s);
		if (ret)
			printf("%d\n", ret);
		else
			printf("Sota!!\n");
	}
	return 0;
}


 

G. 哥德巴赫猜想

问题描述

任一大于2的偶数,都可以表示成两个质数之和。

输入

输入可能包含多个测试样例。

每行包含一个数n (2 <= n <= 100000)

输出

对每个n输出1行,包含两个质数a b,要求a<=b,且a + b = n。若存在多组解,输出a最小那组。

样例输入

4

6

8

10

12

14

样例输出

2 2

3 3

3 5

3 7

5 7

3 11

提示

质数:只能被1和自己整除的正整数,现代数学认为1不是质数。

10 = 3 + 7 = 5 + 5

输出的是3 7,而非5 5

http://blog.csdn.net/fuzimango/article/details/7442143 感觉这个版本更优啊~

 

#include <stdio.h>
#include <string.h>

typedef unsigned int uint;

uint flags[100000 / 2 / sizeof(uint) + 1];
uint prime[5140] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317};

void makePrimeFlag(uint max, int s = 0, int c = -1)
{
	if (c < 0)
		for (c = 0; prime[c]; ++c);

	for (int i = s; i < c; ++i)
	{
		uint d = max / prime[i];
		for (uint r = 3; r <= d; r += 2)
		{
			uint n = prime[i] * r / 2;
			flags[n / sizeof(uint)] &= ~(0x1 << (n % sizeof(uint)));
		}
	}
}

bool isPrime(uint n)
{
	if (n == 2)
		return true;

	if (!(n & 0x1))
		return false;
	n >>= 1;
	return (flags[n / sizeof(uint)] >> (n % sizeof(uint))) & 0x1;
}

void getPrime(uint max)
{
	uint c = 0;
	while (prime[c])
		++c;

	for (uint i = prime[c - 1] + 2; i <= max; i += 2)
		if (isPrime(i))
			prime[c++] = i;
}

int main()
{
	memset(flags, 0xFF, sizeof(flags));
	makePrimeFlag(100000, 1);
	getPrime(50000);

	uint n;
	while (scanf("%u", &n) != EOF)
	{
		for (uint i = 0; prime[i] && prime[i] <= n / 2; ++i)
			if (isPrime(n - prime[i]))
			{
				printf("%d %d\n", prime[i], n - prime[i]);
				break;
			}
	}
	return 0;
}


 

H. 篱笆

问题描述

今年植树节的时候,学校“又”组织同学们在一片空地上种下了一批树。为了逃离“今年在哪儿种,明年还在哪儿种”的命运,学校决定给这批小树围上篱笆。因为种树的时候大家都是随意下铲子的,树种得比较乱,学校又没有太多钱,于是打算用最外围的一圈树做桩,用铁丝网把这圈树给围起来。现在负责的老师要算到底要买多长的铁丝网才能把这圈树围完。

作为一个好好学生,你毫不犹豫的担当起这个重任。

输入

输入可能包含多个测试样例。

第一行包含一个数n (3 <= n <= 100000)

接下来n行包含两个数x y,表示在坐标x y上有一棵树 (0 <= x, y <= 1000)

输出

对每一个测试样例输出一个数k,表示篱笆最小长度,结果保留3位小数。

样例输入

9

200 400

300 400

300 300

400 300

400 400

500 400

500 200

350 200

200 200

样例输出

1000.000

 

#include <stdio.h>
#include <vector>
#include <math.h>

using namespace std;

struct Point
{
	int x, y;
	Point()
	{ }
	Point(const int xx, const int yy)
		: x(xx)
		, y(yy)
	{ }
};
int n;

double pointDistToLine(const int A, const int B, const int C, const Point &p)
{
	return fabs(double(A * p.x + B * p.y + C)) / sqrt(double(A * A + B * B));
}

bool isVectorPositive(const Point &a, const Point &b, bool includeZero = true)
{
	int c = a.x * b.x + a.y * b.y;
	return c > 0 || (includeZero && c == 0);
}

Point calcExpandVector(const Point &a, const Point &b, const Point &vector)
{
	int A = a.y - b.y;
	int B = b.x - a.x;

	Point ret(A, B);
	if (isVectorPositive(vector, ret))
		return ret;

	ret = Point(-A, -B);
	return ret;
}

void splitPointSet(const Point &p, const Point &ve1, const Point &ve2, vector<Point> &ps1, vector<Point> &ps2, const vector<Point> src)
{
	for (vector<Point>::const_iterator itor = src.begin(); itor != src.end(); ++itor)
	{
		Point ne(itor->x - p.x, itor->y - p.y);
		if (!ne.x && !ne.y)
			continue;

		if (isVectorPositive(ve1, ne, false))
			ps1.push_back(*itor);
		else if (isVectorPositive(ve2, ne, false))
			ps2.push_back(*itor);
	}
}

double _QuickHull(const Point &a, const Point &b, const Point &ve, const vector<Point> &pointSet)
{
	if (pointSet.empty())
		return sqrt(double((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)));

	int A = a.y - b.y;
	int B = b.x - a.x;
	int C = a.x * b.y - b.x * a.y;

	Point next;
	double maxd = -1;
	for (vector<Point>::const_iterator itor = pointSet.begin(); itor != pointSet.end(); ++itor)
	{
		if (maxd < pointDistToLine(A, B, C, *itor))
		{
			next = *itor;
			maxd = pointDistToLine(A, B, C, next);
		}
	}

	vector<Point> ps1, ps2;
	Point ve1 = calcExpandVector(a, next, ve);
	Point ve2 = calcExpandVector(b, next, ve);
	splitPointSet(next, ve1, ve2, ps1, ps2, pointSet);

	return _QuickHull(a, next, ve1, ps1) + _QuickHull(next, b, ve2, ps2);
}

double QuickHull(vector<Point> &pointSet)
{
	vector<Point>::iterator pLeft, pRight;
	pLeft = pRight = pointSet.begin();
	for (vector<Point>::iterator p = pointSet.begin() + 1; p != pointSet.end(); ++p)
	{
		if (pLeft->x > p->x)
			pLeft = p;
		else if (pRight->x < p->x)
			pRight = p;
	}

	vector<Point> ps1, ps2;
	Point ve1(pLeft->y - pRight->y, pRight->x - pLeft->x);
	Point ve2(-ve1.x, -ve1.y);
	Point pa = *pLeft;
	Point pb = *pRight;
	pointSet.erase(pRight);
	splitPointSet(pa, ve1, ve2, ps1, ps2, pointSet);
	return _QuickHull(pa, pb, ve1, ps1) + _QuickHull(pa, pb, ve2, ps2);
}

int main()
{
	while (scanf("%d", &n) != EOF)
	{
		vector<Point> pointSet(n);
		for (int i = 0; i < n; ++i)
			scanf("%d %d", &pointSet[i].x, &pointSet[i].y);
		printf("%.3lf\n", QuickHull(pointSet));
	}
	return 0;
}


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值