牛客5(京东)

保卫方案

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

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

输入例子1:
5
1 2 4 5 3

输出例子1:
7

根据左神的思路,写了一下单调栈,写蒙了这个题,通过了90%.
您的代码已保存
内存超限:您的程序使用了超过限制的内存
case通过率为90.00%

#coding=utf-8
import sys
while True:
    try:
        num=int(sys.stdin.readline())
        nums=map(int,sys.stdin.readline().split())
        if len(nums)==0 or len(nums)==1:
            print 0
        else:
            nums1=[[nums[0],1]]
            for i in range(1,num):
                if nums[i]!=nums[i-1]:
                    nums1.append([nums[i],1])
                else:
                    nums1[-1][1]+=1
            if len(nums1)==1:
                print nums1[0][1]*(nums1[0][1]-1)/2
            else:
                ans=[]
                result=0
                i=0
                while i<len(nums1):
                    if len(ans)>0:
                        if nums1[i][0]<ans[-1][0]:
                            ans.append([nums1[i][0],nums1[i][1]])
                            i+=1
                        elif nums1[i][0]>ans[-1][0]:
                            result+=ans[-1][1]*(ans[-1][1]-1)/2+2*ans[-1][1]
                            ans.pop()
                        else:
                            ans[-1][1]+=nums1[i][1]
                            i+=1
                    else:
                        ans.append([nums1[i][0],nums1[i][1]])
                        i+=1
                    if i==len(nums1):
                        while len(ans)>2: 
                            result+=ans[-1][1]*(ans[-1][1]-1)/2+2*ans[-1][1]
                            ans.pop()
                        if len(ans)==2:
                            result+=ans[-1][1]*(ans[-1][1]-1)/2+ans[-2][1]*ans[-1][1]
                            ans.pop()
                        if len(ans)==1:
                            result+=ans[-1][1]*(ans[-1][1]-1)/2
                print result

    except:
        break

按照左神的代码改了一下,还是90%

#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

进制均值

尽管是一个CS专业的学生,小B的数学基础很好并对数值计算有着特别的兴趣,喜欢用计算机程序来解决数学问题,现在,她正在玩一个数值变换的游戏。她发现计算机中经常用不同的进制表示一个数,如十进制数123表达为16进制时只包含两位数7、11(B),用八进制表示为三位数1、7、3,按不同进制表达时,各个位数的和也不同,如上述例子中十六进制和八进制中各位数的和分别是18和11,。 小B感兴趣的是,一个数A如果按2到A-1进制表达时,各个位数之和的均值是多少?她希望你能帮她解决这个问题? 所有的计算均基于十进制进行,结果也用十进制表示为不可约简的分数形式。
输入描述:

输入中有多组测试数据,每组测试数据为一个整数A(1 ≤ A ≤ 5000).

输出描述:

对每组测试数据,在单独的行中以X/Y的形式输出结果。
示例1
输入

5
3
输出

7/3
2/1

#coding=utf-8
import sys


while True:
    try:
        num=input()
        res=0
        for i in range(2,num):
            temp=0
            num1=num
            while num1>=i:
                temp+=num1%i
                num1/=i
            temp+=num1
            res+=temp
        a=res;b=num-2
        while b!=0:
            t=a%b
            a=b
            b=t
        print str(res/a)+'/'+str((num-2)/a)
    except:
        break

幸运数

小明同学学习了不同的进制之后,拿起了一些数字做起了游戏。小明同学知道,在日常生活中我们最常用的是十进制数,而在计算机中,二进制数也很常用。现在对于一个数字x,小明同学定义出了两个函数f(x)和g(x)。 f(x)表示把x这个数用十进制写出后各个数位上的数字之和。如f(123)=1+2+3=6。 g(x)表示把x这个数用二进制写出后各个数位上的数字之和。如123的二进制表示为1111011,那么,g(123)=1+1+1+1+0+1+1=6。 小明同学发现对于一些正整数x满足f(x)=g(x),他把这种数称为幸运数,现在他想知道,小于等于n的幸运数有多少个?
输入描述:

每组数据输入一个数n(n<=100000)

输出描述:

每组数据输出一行,小于等于n的幸运数个数。
示例1
输入

21
输出

3

#coding=utf-8
import sys

def f(n):
    res=0
    while n>0:
        res+=n%10
        n/=10
    return res

def g(n):
    b=str(bin(n))
    return b.count('1')

while True:
    try:
        num=input()
        res=0
        for i in range(1,num+1):
            if f(i)==g(i):
                res+=1
        print res

    except:
        break

集合

给你两个集合,要求{A} + {B}。 注:同一个集合中不会有两个相同的元素。
输入描述:

每组输入数据分为三行,第一行有两个数字n,m(0 ≤ n,m ≤ 10000),分别表示集合A和集合B的元素个数。后两行分别表示集合A和集合B。每个元素为不超过int范围的整数,每个元素之间有个空格隔开。

输出描述:

针对每组数据输出一行数据,表示合并后的集合,要求从小到大输出,每个元素之间有一个空格隔开,行末无空格。
示例1
输入

3 3
1 3 5
2 4 6
输出

1 2 3 4 5 6
想用合并排序,结果出问题了。。。。。
就直接最简的了

#coding=utf-8
import sys

while True:
    try:
       num=sys.stdin.readline().split()
       n,m=int(num[0]),int(num[1])
       ns=map(int,sys.stdin.readline().split())
       ms=map(int,sys.stdin.readline().split())
       res=list(set(ns).union(set(ms)))
       res.sort()
       print ' '.join(map(str,res))
    except:
        break
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值