济南集训的第一天
分治
发现了这道题
jio的还不错
于是
找了一找
那么
基本思想----分治、极角排序
---------------------------------------------------------------------------------------------
巨人与鬼:
题目:
一组n个巨人正与n个鬼进行战斗,每个巨人的武器是一个质子炮, 它可以把一串质子流射中鬼而把鬼消灭。质子流沿直线行进,在击中鬼时就终止。巨人决定采取下述策略。他们寻找鬼配对,以形成n个巨人─鬼对,。然后每个巨人同时向他选取的鬼射出一串质子流。我们知道,让质子流互相交叉是很危险的。因此巨人选择的配对方式应该使质子流都不会交叉。假定每个巨人和每个鬼的位置都是平面上的一个固定点,并且没有三个位置共线, 求一种配对方案。
下面的输入是笔者自己设计的:
输入:
有多组输入,第一行为n,第二行为n个巨人的坐标(浮点型),第三行为n个巨人的坐标(浮点型)
输出:
巨人编号(这里的编号就是各坐标输入的次序0——2*n-1)--鬼的编号。
样例输入:
2
0 0 1 2
2 1 -1 4
样例输出(有可能有多种匹配方案,只要符合要求即可):
0--2
1--3
-----------------------------------------------------------------------------------------------------------------------------
这一题书上说是分治+递归,但是笔者刚开始只是当成数理题做,并没有意识到其分治的思想,下面的代码也是按照笔者最开始的数理方法写的,分治思想的代码之后再补上。
1 .首先,要如何想到这种极坐标的结构呢?事实上,可以这么想:对于一个巨人A,比如下图远点位置的蓝圆圈,总要有一个鬼和它配对(题中说n个鬼,n个巨人),因此,现在我们要在n个鬼当中选1个鬼给巨人A怼,这样就很自然地想到以该巨人A为原点,鬼们绕着这个巨人,这样再来考虑如何选鬼被巨人A怼会直观一些,考虑到题目中说,巨人选择的配对方式应该使质子流都不会交叉,因此我们还要考虑其它巨人的空间位置。
2. 如果选图中鬼1,接下去巨人B——鬼2,巨人C——鬼3,看似没什么毛病,但是要注意,如果我们选巨人A——鬼1,那么巨人B——鬼2很可能与质子流巨人A——鬼1相撞,那么怎么办呢,有没有一种优美的方法能天然地避开这种撞击问题呢?诶,还真有:从下图中的x轴正向出发,沿着逆时针方向找到第一个安全鬼(解释一下安全鬼:在下图中就是鬼2,因为鬼1前面还有一个巨人B,为了避免B的质子流与A的质子流相撞,安全起见,我们把鬼1让给B,找下一个鬼怼,所以如果鬼1和鬼2之间还有一个巨人E,那么鬼2也得让给巨人B、E,找下一个安全鬼。)
3.有些细心的同学就会问:我们该从哪个巨人开始匹配,好,给大家一点时间捋一捋,想一想:
好,我们该从哪个巨人开始匹配呢?答案是:从最底下的那个巨人开始匹配,为什么呢?请看下图:
如果我们不从位于最下面的巨人B开始匹配,而从上面一点A的开始匹配,采用刚才上面讨论的方法,得到:巨人A——鬼1,好,这样就会有问题了,巨人B潜伏在下面,很可能就会一箭射穿巨人A——鬼1质子流,但是如果我们每次都从最下面的巨人开始匹配的话,就排除了有潜在巨人在x轴下面的隐患,当然鬼是可以在x轴下面的。
4. 好,基本策略我们已经弄清了,现在代码要怎么写呢?不,应该问伪代码要怎么写呢?来,借一步说话——>
1.找到当前最下面的巨人A,且该巨人A没被访问过
2.以该巨人A为原点,以逆时针方向(这里涉及到按角度排序)找到第一个未被访问的安全鬼,匹配之
3.标记该巨人A和匹配的鬼被访问过。
4.如果还有巨人未匹配,转1.