题解:蓝桥云课 3075 特殊的多边形

【题目来源】

蓝桥云课:1.特殊的多边形 - 蓝桥云课 (lanqiao.cn)

【题目描述】

假设一个 \(n\) 边形 \(n\) 条边为 \(a_1,a_2,a_3,…,a_n\),定义该 \(n\) 边形的值 \(v=a_1×a_2×a_3×...×a_n\)

定义两个 \(n\) 边形不同是指至少有一条边的长度在一个 \(n\) 边形中有使用而另一个 \(n\) 边形没有用到,如 \(n\) 边形 \((3,4,5,6)\)\((3,5,4,6)\) 是两个相同的 \(n\) 边形,\((3,4,5,6)\)\((4,5,6,7)\) 是两个不相同的 \(n\) 边形。

现在有 \(t\)\(n\),表示 \(t\) 个询问并且询问的是 \(n\) 边形,每个询问给定一个区间 \([l,r]\),问有多少个 \(n\) 边形(要求该 \(n\) 边形自己的 \(n\) 条边的长度互不相同)的值在该区间范围内。

【输入】

第一行包含两个正整数 \(t\)\(n\),表示有 \(t\) 个询问,询问的是 \(n\) 边形。

接下来 \(t\) 行,每行有两个空格隔开的正整数 \(l\)\(r\),表示询问区间\([l,r]\)

【输出】

输出共 \(t\) 行,第 \(i\) 行对应第 \(i\) 个查询的 \(n\) 边形个数。

【输入样例】

4 3
1 10
30 50
60 200
200 400

【输出样例】

0
1
18
32

【算法标签】

《蓝桥云课 3008 特殊的多边形》 #前缀和# #搜索# #DFS#

【代码详解】

#利用DFS求所有的N边形,边长乘积不超过100000
#N边形:最小的N-1条边之和>第N边,即tot - path[-1] > pathp[-1]
def dfs(depth, last_val, tot, mul):
  """
  depth: 第几条边
  last_val: 上一条边的边长
  tot: 当前所有边长之和
  mul: 当前所有边长之积
  """
  if depth == n:
    #N边形的条件
    if tot > 2 * path[-1]:
      #此时是一个合法的N边形
      ans[mul] += 1
    return
    #枚举第depth条边的边长为i
  for i in range(last_val + 1, 100000):
    #最优性剪枝:要保证乘积不超过100000
    #先前选择了depth个数字,乘积为mul
    #后续还有n-depth个数字,每个数字都要>i
    if mul * (i**(n-depth)) <= 100000:
      path.append(i)
      dfs(depth+1, i, tot+i, mul*i)
      path.pop()
    else:
      break

#ans[i]表示价值为i的N边形数目
ans = [0] * 1000001
t, n = map(int, input().split())
path = []
dfs(0, 0, 0, 1)
#每次询问一个区间l, r,输出有多少个N边形的价值在[l,r]中
#等价于ans[l]+...ans[r],所以需要对ans求前缀和
for i in range(100001):
  ans[i] += ans[i-1]
for _ in range(t):
  l, r = map(int, input().split())
  print(ans[r]-ans[l-1])

【运行结果】

4 3
1 10
30 50
60 200
200 400
0
1
18
32
posted @ 2026-03-04 15:20  团爸讲算法  阅读(0)  评论(0)    收藏  举报