2023년 12월 GESP Python 레벨 6 프로그래밍 실제 시험 문제 분석

6. 2023년 12월 GESP Python 레벨 6 프로그래밍 질문

[레벨 6 프로그래밍 질문 1]

[시험문제명] : 레벨 깨기 게임

제한시간 : 2.0초

메모리 제한 : 128.0MB

문제 설명】

당신은 레벨을 깨는 게임에 도착했습니다.

이 게임은 총 N 개의 레벨로 구성되어 있으며, 각 레벨에는 M개의 채널이 있으며, 채널을 선택하고 다음 레벨로 이동해야 합니다. 그 중 i- 번째 채널을 이용하면 ai 레벨 로 올라갈 수 있는데 , 즉 현재 x 레벨에 있다면 i- 번째 채널을 선택하면 곧바로 x + ai 레벨로 올라오게 된다 (특히, x + aiN 이면 레벨을 통과합니다. 또한 레벨 S를 성공적으로 종료하면 bs 포인트 도 얻을 수 있습니다 .

게임이 시작되면 레벨 0 이 됩니다 . 레벨 클리어 시 얻을 수 있는 최대 총점은 얼마인지 알려주세요.

[ 설명 입력]

첫 번째 줄의 두 정수 MN 은 각각 각 레벨의 레벨 수와 채널 수를 나타냅니다.

다음 줄에는 단일 공백으로 구분된 M 개의 정수 a 0 , a 1,…, aM -1 이 포함됩니다 . 1 aiN 이 보장됩니다 .

다음 줄에는 단일 공백으로 구분된 N 개의 정수 b 0 , b 1,…, bM -1 이 포함됩니다 . 보장 | bi | 10⁵ .

[ 출력 설명]

한 줄에 하나의 정수로, 레벨을 통과할 때 얻을 수 있는 최대 점수를 나타냅니다.

【데이터 규모】

테스트 포인트의 20% 에 대해 M =1 이 보장됩니다 .

테스트 포인트의 40% 에 대해 N20 이 보장되고 M2 가 보장됩니다 .

모든 테스트 포인트에 대해 N10⁴ 이 보장 되고 M100 이 보장됩니다 .

【분석】

방법 1

" 재귀적 " 알고리즘을 사용하여 레벨 0 부터 가장 높은 점수를 가진 레벨까지 각 채널을 선택합니다 ( 0 점 및 음수 정렬 채널 방지 ) . 각 레벨에서 각 채널을 선택하고 점수가 기존 값보다 크면 업데이트합니다.

시간 복잡도: O ( NM ) , 10⁴ ×100≤ 10⁶ , 시간 초과 없음.

【완전한 코드】

n, m = [int(i) for i in input().split()]
a = [int(i) for i in input().split()]
b = [int(i) for i in input().split()]
dp = [0] * (n + 1)                                   # 到第i关获得的最高得分
for i in range(n):
    for j in range(m):
        t = min(i + a[j], n)                         # 最高通关数为第n关
        if dp[t] == 0:
            dp[t] = dp[i] + b[i]
        else:
            dp[t] = max(dp[t], dp[i] + b[i])         # 考虑有负值的情况,取大者
print(dp[n])

【작업 결과】

방법 2

레벨 0을 통과하면 1 점 의 가치가 있습니다 . (b[0]) 각 레벨을 " 횡단 " 하고 각 채널을 " 횡단 " 합니다. 이전 레벨에 클리어한 점수가 있는 경우 해당 레벨의 점수와 해당 점수로 계산됩니다. 최대값이 사용됩니다 ( 0 점을 피하기 위해 음수 정렬 채널 ) .

시간 복잡도: O ( NM ) , 10⁴ ×100≤ 10⁶ , 시간 초과 없음.

【완전한 코드】

n, m = [int(i) for i in input().split()]
a = [int(i) for i in input().split()]
b = [int(i) for i in input().split()]
f = [b[0]]                                                 # 添加第0关分
for i in range(1, n):
    f.append(0)                                            # 本关初始0分
    for pway in a:
        if i - pway >= 0 and f[i - pway]:                  # 上一关存在并有分值
            # 本站已有分值时,取本站与上一站分中大者,否则取上一站分
            f[i] = max(f[i], f[i - pway]) if f[i] else f[i - pway]
    if f[i]:                                               # 本关通过加b[i],负分不加
        f[i] += max(0, b[i])                               # 负分通道不走(避免进入负分关)
print(f[i])

【작업 결과】

[레벨 6 프로그래밍 문제 2 ]

[시험문제명] : 업무소통

시간 제한: 2.0초

메모리 제한: 128.0MB

문제 설명】

회사에는 0 부터 N -1 까지 번호가 매겨진 N명의 직원이 있습니다 . 그 중 상사인 0 번 사원을 제외한 모든 사원에게는 직속 상사가 있습니다. i직원의 직속 상사 가 fi 라고 가정합니다 .

회사는 엄격한 관리 시스템을 갖추고 있으며 각 직원은 직접 또는 간접적인 리더십에 의해서만 관리될 수 있습니다. 특히 x = y 또는 x = fy 또는 x가 fy 를 관리할 수 있는 경우에만 직원 x가 직원 y 를 관리할 수 있다고 규정되어 있습니다 . 특히 0 번 사원의 상사는 자신만 관리할 수 있고 다른 직원은 관리할 수 없습니다.

이제 일부 동료가 협업을 원하고, 협업을 진행해 줄 동료를 찾고 싶은데, 이 동료는 협업에 참여하는 모든 동료를 관리할 수 있어야 합니다. 이 조건을 충족하는 직원이 여러 명이라면 가장 높은 숫자를 가진 직원을 찾으려고 합니다. 그들을 도울 수 있나요?

[ 설명 입력]

첫 번째 줄에는 직원 수를 나타내는 정수 N 이 포함됩니다.

두 번째 줄에는 공백으로 구분된 N 개의 양의 정수( f 1 , f 2 ,…, fN -1 )가 포함되어 있습니다 .

세 번째 줄에는 정수 Q 가 포함되어 있으며, 이는 정리해야 할 Q 개의 경우가 있음을 나타냅니다 .

다음은 Q 라인이며 각 라인은 협력을 설명합니다. 시작은 이 협력에 참여하는 직원 수를 나타내는 정수 m (2 mN ) 이고 그 뒤에는 참여하는 직원 수를 나타내는 m 정수가 옵니다. 이 협력 ( 번호가 합법적이고 반복되지 않는지 확인 ) .

회사 구조가 합법적인지 확인하십시오. 즉, 직간접적인 리더인 직원이 없는지 확인하십시오.

[ 출력 설명]

출력 Q 라인, 각 라인에는 각 협력의 호스트에 대해 차례로 선택되는 정수가 있습니다.

데이터 규모 】

테스트 포인트의 50% 에 대해 N ≤ 50 이 보장됩니다 .

모든 테스트 포인트에 대해 3≤ N ≤300 , Q ≤100 이 보장됩니다 .

【분석】

방법 1

먼저 레이어별 상향 ( 재귀 ) 방식을 사용하여 각 개인의 모든 리더를 찾아 2차원 목록에 표시하고 , 각 팀별로 가장 높은 숫자를 가진 공통 리더를 하나씩 찾습니다. 답변.

시간 복잡도: O ( QNM ) ≤ O ( QN ²) , 100 × 300² 9 × 10⁶©107 , 시간 초과 없음.

【완전한 코드】

n = int(input())
mngr = [[] for i in range(n)]                 # 不能用[[]]*n
for k in [(i,int(j)) for i,j in enumerate(input().split())]:
    mngr[k[1]].append(k[0]+1)
rel = [[0] * n for i in range(n)]             # “行”为领导编号,“列”为员工编号
def dfs(row,col):
    rel[row][col] = 1                         # 存在领导关系则为1, 否则是0
    for c in mngr[col]:
        dfs(row,c)
for i in range(n):                            # 建每个人的所有领导关系(直接、间接)表
    dfs(i,i)
q = int(input())
for _ in range(q):
    x = [int(i) for i in input().split()][1:] # 第1个是人数本处用不上,丢弃
    ans = -1
    for r in range(n):
        for y in x:
            if not rel[r][y]:                 # 每位员工r都是领导,则不会break
                break
        else:
            ans = r
    print(ans)

【작업 결과】

방법 2

먼저, 각 개인의 직접 리더십과 간접 리더십을 단계별로 활용하여 2차원 목록으로 표시하고 , 각 팀별로 가장 높은 숫자를 가진 공통 리더를 하나씩 찾아내는 것이 답이다.

시간 복잡도: O ( QMN ) O ( QN² ) , 100 × 300² 9 × 10⁶©107 , 시간 초과 없음.

【완전한 코드】

n = int(input())
b = [[0] * n for i in range(n)]
f = [0]+[int(i) for i in input().split()]             # 直接领导关系
for i in range(n):                                    # 间接领导关系b[i][j]为1表示i是j的领导
    b[i][i] = 1                                       # 自己可以管自己
    b[0][i] = 1                                       # 老板管所有员工
    sup = f[i]                                        # 找直接领导
    while sup:                                        # 领导不是老板就继续找
        b[sup][i] = 1;
        sup = f[sup]                                  # 找间接领导(领导的领导)
q = int(input())
for _ in range(q):
    a = [int(i) for i in input().split()]             # 第1个a[0]是人数, 每次合作的员工列表
    for i in range(2, a[0]+1):                        # 从第2个员工开始找与前面员工的共同领导
        for j in range(min(a[i], a[i - 1]), -1, -1):  # 从编号最小的开始
            if b[j][a[i]] and b[j][a[i - 1]]:         # 如果是共同领导
                a[i] = j                              # 当前员工换成共同领导
                break   
print(a[a[0]])

【작업 결과】

추천

출처blog.csdn.net/hz_zhangrl/article/details/135237822