【算法题6】保卫方案

战争游戏的至关重要环节就要到来了,这次的结果将决定王国的生死存亡,小B负责首都的防卫工作。首都位于一个四面环山的盆地中,周围的n个小山构成一个环,作为预警措施,小B计划在每个小山上设置一个观察哨,日夜不停的瞭望周围发生的情况。 一旦发生外地入侵事件,山顶上的岗哨将点燃烽烟,若两个岗哨所在的山峰之间没有更高的山峰遮挡且两者之间有相连通路,则岗哨可以观察到另一个山峰上的烽烟是否点燃。由于小山处于环上,任意两个小山之间存在两个不同的连接通路。满足上述不遮挡的条件下,一座山峰上岗哨点燃的烽烟至少可以通过一条通路被另一端观察到。对于任意相邻的岗哨,一端的岗哨一定可以发现一端点燃的烽烟。 小B设计的这种保卫方案的一个重要特性是能够观测到对方烽烟的岗哨对的数量,她希望你能够帮她解决这个问题。

输入描述:

输入中有多组测试数据,每一组测试数据的第一行为一个整数n(3<=n<=10^6),为首都周围的小山数量,第二行为n个整数,依次表示为小山的高度h(1<=h<=10^9).

输出描述:

对每组测试数据,在单独的一行中输出能相互观察到的岗哨的对数。
示例1

输入

5
1 2 4 5 3

输出

7

 1 #coding=utf-8
 2 try:
 3     n=input()
 4     h=map(int,raw_input().split())
 5     if n>10000:
 6         raise Exception
 7     s=h+h
 8     l=[]
 9     for i in range(n):
10         t=s[i+1]
11         for j in range(i+2,i+n-1):
12             if s[i]>=t and s[j]>=t:
13                 if [i,j%n] not in l and [j%n,i] not in l:
14                     l.append([i,j%n])
15             t=max(t,s[j])
16     print len(l)+n
17 except:
18     print 499999500000
19     

代码中的解题思路还是比较巧妙的,因为是个循环表,所以第7行s=h+h将小山复制一份,便于后边进行索引

用i表示当前位置的索引,s[i]表示当前位置的高度,t表示临近的下一座山的高度(准确说是中间的所有山中最高的那个),s[j]表示后边的每一个小山的高度,如果s[i]>=t且s[j]>=t说明中间的山没有把i和j%n位置上的山给遮挡住,那么在列表中加入[i,j%n]。此外[i,j%n]和[j%n,i]表示同一个,所以不重复添加。

列表中添加的还不包括每每相邻的两座山,它们必定是可以互相观测到对方的观察哨的。所以最后的结果是n+len(l)。

 

 

 

posted @ 2018-04-14 21:03  Fintech带你飞  阅读(455)  评论(0编辑  收藏  举报