首页 > 试题广场 >

保卫方案

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

数据范围: , 每座山的高度满足

输入描述:
输入中有多组测试数据,每一组测试数据的第一行为一个整数 n ,为首都周围的小山数量,第二行为n个整数,依次表示为小山的高度 h


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

输入

5
1 2 4 5 3

输出

7
示例2

输入

3
1 2 1

输出

3

说明

相邻的一定能直接看到  
import sys
sys.setrecursionlimit(100000) #例如这里设置为十万  n = int(input())
num = list(map(int,input().split()))
count = 0  def f1(array): global count m = len(array) for i in range(1,m): if array[0] >= array[i] and array[i] <= array[i+1]:
           count += 1  else: break  array = array[1:]+[array[0]]
  f1(array) return count  print(f1(num)+n)

以num[0]为第一个山峰 找与它相关的对数 怎么不对
发表于 2018-10-30 15:38:55 回复(0)
def nextIndex(n,i):
    if i<n-1:#当最高山峰下标不是最后一个时,下一个下标直接加1
        return i+1
    return 0#最高山峰下标是最后一个,下一个下标为0

def getInternalSum(n):#相同元素计算内部对数,组合数C(n,2)
    return n*(n-1)/2

while 1:
    try:
        n=int(input())
        h=list(map(int,input().split()))
    except:
        break
    if n<2:
        ans=0
    else:
        m=max(h)#最高山峰的值
        maxIndex=h.index(m)#记录最高山峰的下标
        index=nextIndex(n,maxIndex) #移到最高山峰下标的下一个
        ans=0
        stack=[]
        stack.append([m,1])#将最大值压入栈底
        while index!=maxIndex:#index=maxIndex时,则对所有元素完成一轮扫描
            value=h[index]
            while len(stack)>0 and stack[-1][0]<value: #如果栈顶元素小于当前元素
                times=stack[-1][1]#记录栈顶元素的个数
                stack.pop()#栈顶元素出栈
                ans+=getInternalSum(times)+times#内部对数+它右边相邻的数能看到所有的该数
                if len(stack)>0:#如果栈中还有元素,则它左边相邻的数也能看到所有的该数
                    ans+=times
            if len(stack)>0 and stack[-1][0]==value: #栈顶元素和当前元素相当,+1
                stack[-1][1]+=1#该元素的个数+1
            else:#栈顶元素大于当前元素,则将当前元素压入栈,个数为1
                stack.append([value,1])
            index=nextIndex(n,index)#下一个数
        while len(stack)>0:#扫描完所有的元素后,若栈不为空
            times=stack[-1][1]#栈顶元素的个数
            stack.pop()#栈顶元素出栈
            ans+=getInternalSum(times)#栈顶元素内部的对数
            if len(stack)>0:#若它左边还有更大的数
                ans+=times#则相邻数能看到所有的该数
                if len(stack)>1:#若左边比它大的元素不止一个值
                    ans+=times#由于是环形,栈底元素也可看到所有的该值
                else:
                    if stack[-1][1]>1:#若左边相邻的数即为栈底元素,且个数大于1
                        ans+=times#由于是环形,则另一端也可看到所有的该值
    print(int(ans))

发表于 2018-06-24 14:08:32 回复(0)
单调栈,很烦!
import bisect
import heapq
import functools
import time
import random
import itertools
import math
import sys
n = int(input())
list_x = [int(x) for x in input().split()]
result_x = []
temp_x = [list_x[0],1]
for x in list_x[1:]:
    if x==temp_x[0]:
        temp_x[1] += 1
    else:
        result_x.append(temp_x)
        temp_x = [x,1]
result_x.append(temp_x)
max_value = max([i[0] for i in result_x])
max_index = [i[0] for i in result_x].index(max_value)
result_x = result_x[max_index:]+result_x[:max_index]
stack = [result_x.pop(0)]
ans = 0
for x in result_x:
    if stack[-1][0]>x[0]:
        stack.append(x)
    elif stack[-1][0] == x[0]:
        stack[-1][1] = stack[-1][1]+x[1]
    elif stack[-1][0]<x[0]:
        while stack[-1][0]<x[0]:
            ans+=(stack[-1][1]*(stack[-1][1]-1)/2+2*stack[-1][1])
            stack.pop()
        if x[0] == stack[-1][0]:
            stack[-1][1] = stack[-1][1] + x[1]
        else:
            stack.append(x)
while len(stack)>2:
    ans+=(stack[-1][1]*(stack[-1][1]-1)/2+2*stack[-1][1])
    stack.pop()
if len(stack)==1:
    ans += stack[-1][1]*(stack[-1][1]-1)/2
elif stack[0][1]==1:
    ans +=  (stack[-1][1]*(stack[-1][1]-1)/2+stack[-1][1])
elif stack[0][1]>1:
    ans += ((stack[-1][1] * (stack[-1][1] - 1) / 2 + 2 * stack[-1][1])+stack[0][1] * (stack[0][1] - 1) / 2)
print(int(ans))
发表于 2018-05-30 14:13:44 回复(0)
import sys
if __name__ == "__main__":
    n = int(sys.stdin.readline().strip())
    mountain = list(map(int,sys.stdin.readline().strip().split()))
    count = 0
    maxNum = max(mountain)
    for i in range(n):
        cur = i + 2
        hider = 0
        for j in range(n-3):
            if cur >= n:
                cur -= n
            if mountain[cur] == maxNum and mountain[i] == maxNum:
                count += 1
                cur += 1
                continue
            if mountain[cur - 1] > mountain[i]:
                break
            elif mountain[cur - 1] <= mountain[cur]:
                if mountain[cur] >= hider:
                    count += 2
            else:
                hider = mountain[cur - 1] if mountain[cur - 1] > hider else hider
            cur += 1
    count = count//2 + n
    print(count)

尽力了。。奈何还是百分之90~

发表于 2018-03-30 01:37:14 回复(0)
  

通过了50%.。。但没想明白是哪里错了??0.0
  for j in range(i+2,n):
        if i==0 and j==n-1:
            pass
        else:
            t=1
            q=1
            for m in range(i,j):
                if l[m]>min(l[i],l[j]):
                    t=0
            for m in range (i+1)or(j,n):
                if l[m]>min(l[i],l[j]):
                    q=0
            out+=t|q
print out 
发表于 2017-08-27 23:57:50 回复(0)
#coding=utf-8
import sys
def nextIndex(num,i):
    if i<num-1:
        return i+1
    return 0
def getInternalSum(n):
    return n*(n-1)/2
while True:
    try:
        num=int(sys.stdin.readline())
        nums=map(int,sys.stdin.readline().split())
        if num<2:
            print 0
        else:
            maxIndex=0
            for i in range(num):
                if nums[maxIndex]<nums[i]: #记录最高山峰的下标
                    maxIndex=i
            value=nums[maxIndex]
            index=nextIndex(num,maxIndex) #移到最高山峰下标的下一个
            res=0
            stack=[]
            stack.append([value,1])
            while index!=maxIndex:
                value=nums[index]
                while len(stack)>0 and stack[-1][0]<value: #如果栈顶元素小于当前元素
                    times=stack[-1][1]
                    stack.pop()
                    res+=getInternalSum(times)+times
                    if len(stack)>0:
                        res+=times
                if len(stack)>0 and stack[-1][0]==value: #栈顶元素和当前元素相当,+1
                    stack[-1][1]+=1
                else:
                    stack.append([value,1])
                index=nextIndex(num,index)
            while len(stack)>0:
                times=stack[-1][1]
                stack.pop()
                res+=getInternalSum(times)
                if len(stack)>0:
                    res+=times
                    if len(stack)>1:
                        res+=times
                    else:
                        if stack[-1][1]>1:
                            res+=times
            print res

    except:
        break

左神的方法,单调栈,90%AC。。。
发表于 2017-07-24 08:29:54 回复(1)