连号区间数【第四届】【省赛】【B组】【第四届】【省赛】【B组】【Python】 理解题意 未AC 60超时

连号区间数【第四届】【省赛】【B组】

  • 题目
  • 分析

题目

描述 :
在1~N的某个全排列中有多少个连号区间呢?这里所说的连号区间的定义是:如果区间[L, R] 里的所有元素(即此排列的第L个到第R个元素)递增排序后能得到一个长度为R-L+1的“连续”数列,则称这个区间连号区间。
输入格式:
第一行是一个正整数N (1 <= N <= 50000), 表示全排列的规模。第二行是N个不同的数字Pi(1 <= Pi <= N), 表示这N个数字的某一全排列。
输出格式:输出一个整数,表示不同连号区间的数目。
用户输入:
4
3 2 4 1
程序应输出:7
用户输入:
5
3 4 2 5 1
程序应输出:9
解释:
第一个用例中,有7个连号区间分别是:[1,1], [1,2], [1,3], [1,4], [2,2], [3,3], [4,4]
第二个用例中,有9个连号区间分别是:[1,1], [1,2], [1,3], [1,4], [1,5], [2,2], [3,3], [4,4], [5,5]

分析

本题搞了半天才读懂,很影响心态!注意题目关键词“区间所有元素” “连续数列” 根据用例来分析!其实很简单

其中一个连号区间是[1,4],表示从第一个元素到第四个元素,也就是3 4 2 5,经过排序后是连续的:对3 4 2 5排序,就得到2 3 4 5,显然2 3 4 5是连续的。

很容易想到暴力,两个for去挑出两个区间头尾元素,对整个区间排序,然后看看是否连续(从小到大全部出现),挑出两个元素我们可以用combinations组合来优化(同时用枚举类型记录组合元素对应的下标)

from itertools import combinations
n=int(input())#4

nums=list(map(int,input().split()))#3 2 4 1
#print(nums)
cnt=n
for x in combinations(enumerate(nums),2):#避免重复,因此cnt默认就为n,自己本身不能取两次
  #print(x)#((0, 3), (1, 2))
  st=x[0][0]#0
  ed=x[1][0]#1
  seq=nums[st:ed+1]
  seq.sort()
  #print(seq)
  l=[x for x in range(seq[0],seq[-1]+1)]
  if len(seq)==len(l):
    cnt+=1
print(cnt)
  

超时60分,但在比赛时候可不会让你一直调试!能不能优化?

(学习一下下面思路)
改变思路,找是否存在规律
题目要求的特定区间 除了需要满足连续性以外 还需要满足下标的某种关系
即子区间的长度=连续区间的长度。详细一点说,我们上面给出的区间,它即是子区间又是连续区间,当把他看作子区间时,他的长度为R-L+1(最左(右)侧对应下标),当把他看作连续区间时,它的长度=6-2+1=5 可以发现=max-min+1

因而题目所要求的就是找到所有满足R-L+1=max-min+1的所有区间的个数

但是这样也就80分

n=int(input())
s=list(map(int,input().split()))
s.insert(0,0)
 
count=0
 
for i in range(1,len(s)):
    for j in range(i,len(s)):
        if j-i+1==max(s[i:j+1])-min(s[i:j+1])+1:
            count+=1
print(count)

你可能感兴趣的:(蓝桥杯真题题解,蓝桥杯,python)