试题算法训练 Two k-Convex Polygons
题目
给定n个棍子的长度和整数k,求能否在其中选出2k个棍子拼成两个凸多边形。使得两个凸多边形都恰好有k跟棍子组成,且任意相邻的边都不共线。
输入
第一行包括两个正整数n,k,表示棍子总数和多边形边数。
第二行包括n个正整数,表示每根棍子的长度。
输出
第一行输出一个单词Yes或者No表示是否能选出满足要求的2k个棍子。
如果第一行输出的是Yes,则第二行要输出方案。输入的棍子从1开始按照输入顺序编号,你需要输出2k个空格隔开的正整数,前k个表示组成第一个凸多边形的棍子的编号,后k个表示组成第二个凸多边形棍子的编号。
如果有多种方案,输出任意一种即可。
样例
样例输入
Input 1:
6 3
1 1 1 2 2 2
Input 2:
6 3
1 2 3 100 200 300
样例输出
Output 1:
Yes
1 2 3 4 5 6
Output 2:
No
我的思路很乱,不过就当作用来练习枚举算法了,写了两个dfs,居然能过35%,属于是我自己也不知道为什么能通过,再练习练习枚举,加油。
n,k = map(int,input().split())
a = input().split()
src = []
for i in range(n):
src.append([a[i],i,0])
src = sorted(src)
A = [0]*k
B = [0]*k
Aflag = 0
Bflag = 0
def dfsA(step):
global Aflag
if Aflag:
# print("Aflag = 1")
return
if step == k:
# print("找到")
tmp = sorted(A)
if sum(tmp[:len(A)-1]) > tmp[len(A)-1]:
# global Aflag
Aflag = 1
return # 递归出口
for i in range(n):
if Aflag == 1:
continue
if src[i][2] == 0 :
A[step] = int(src[i][0])
src[i][2] = 1
dfsA(step+1)
# 找到匹配结果了,不用再重置
if Aflag != 1:
A[step] = 0
src[i][2] = 0
def dfsB(step):
global Bflag
if Bflag:
return
if step == k:
# print("找到")
tmp = sorted(B)
if sum(tmp[:len(B)-1]) > tmp[len(B)-1]:
# global Aflag
Bflag = 1
return # 递归出口
for i in range(n):
if Bflag == 1:
continue
if src[i][2] == 0 :
B[step] = int(src[i][0])
src[i][2] = 1
dfsB(step+1)
# 找到匹配结果了,不用再重置
if Bflag != 1:
B[step] = 0
src[i][2] = 0
dfsA(0)
dfsB(0)
if Aflag&Bflag:
print('Yes')
for i in range(n):
if int(src[i][0]) in A:
src[i][1] == 'visited'
print(src[i][1] + 1,end = ' ')
for i in range(n):
if int(src[i][0]) in B:
if src[i][1] != 'visited':
print(src[i][1] + 1,end = ' ')
else:
print('No')
试题 算法训练 安抚灵魂
这个我感觉自己思路没有问题,感觉答案有问题a。这个房间号不是一直在涨吗,所以都从第一个开始遍历,按照给的递推公式找到小于n的所有情况。但是感觉结果有点迷惑啊......
import sys
sys.setrecursionlimit(1000000)
t = int(input())
src = []
for i in range(t):
src.append(list(map(int,input().split())))
count = 0
def dfs(step,i):
global count
if step>src[i][3]:
count = count + 1
print(count)
return
count = count + 1
dfs(step*src[i][0]+step*src[i][1]+src[i][2],i)
for i in range(t):
count = 0
dfs(0,i)