HNUCM-2023 Spring Semester "Algorithm Analysis and Design" Exercise 3

Keep a record of your own learning.


Problem A: Super Frog

topic description

A super frog can jump up 1 step or 2 steps at a time... It can also jump up n steps. Excuse me, how many ways does the frog jump up an n-level step in total?

enter

Enter a positive integer n to represent the number of steps.

output

Output the total number of hops.

Sample input:
1
2
Sample output:
1
2

The recursive formula is F(n)=2*F(n-1).


def jumpFloorII(number):
    if number <= 0:
        return 0
    if number == 1:
        return 1
    else:
        return 2 * jumpFloorII(number - 1)


while True:
    try:
        print(jumpFloorII(int(input())))
    except:
        break

Problem B: Kimi Sequence

topic description

Kimi is working on a sequence recently:

  • F(0) = 7
  • F(1) = 11
  • F(n) = F(n-1) + F(n-2) (n≥2) Kimi is called the Kimi sequence. Please help to confirm whether the nth number in the sequence is a multiple of 3.

enter

The input contains multiple sets of data. Each set of data contains an integer n, (0≤n≤30).

output

There is one line of output for each set of inputs. If F(n) is a multiple of 3, output "Yes"; otherwise, output "No".

Example Import:
0
1
2
3
4
5
Example Export:
No
No
Yes
No
No
No

simple recursion


f = [7, 11]
for i in range(2, 32):
    f.append(f[i - 1] + f[i - 2])
while True:
    try:
        n = int(input())
        if f[n] % 3 == 0:
            print('Yes')
        else:
            print('No')
    except:
        break

Problem C: Tower of Hanoi

topic description

Use recursion to write a program to implement the Tower of Hanoi problem. It is required to output the moving steps of the discs after inputting the number of discs. The output format example is as follows: Step 1: No. 1 disc moves from column A to column B. Step 2:
2 Number plate moved from A-pillar to C-pillar

enter

Multiple sets of test cases, each input a positive integer n, n represents the number of discs.

output

There is a blank line between each set of output.

Sample Input:
3
Sample Output:
Step 1: Disk #1 moves from Pillar A to Pillar C
Step 2: Disk #2 moves from Pillar A to Pillar B
Step 3: Disk #1 moves from Pillar C to Pillar B Pillars
Step 4: Disk 3 moves from Pillar A to Pillar C
Step 5: Disk 1 moves from Pillar B to Pillar A
Step 6: Disk 2 moves from Pillar B to Pillar C
Step 7: Disk 1 Move from A-pillar to C-pillar

The topic is not difficult, but you must pay attention to the fact that there is a newline between the outputs! ! ! , using a dictionary to store the number of each plate.


def move(idd, s1, s2):
   global i
   i += 1
   if i == nn:
       print(f"第{
      
      i}步:{
      
      idd}号盘从{
      
      s1}柱移至{
      
      s2}柱")
   else:
       print(f"第{
      
      i}步:{
      
      idd}号盘从{
      
      s1}柱移至{
      
      s2}柱 ")


def hanoi(n, a, b, c):
   if n == 1:
       move(dist[n], a, c)
   else:
       hanoi(n-1, a, c, b)
       move(dist[n], a, c)
       hanoi(n-1, b, a, c)


while True:
   try:
       n = int(input())
       nn = 2**n-1
       dist = {
    
    }
       c = 1
       i = 0
       for k in range(1, n+1):
           if k not in dist:
               dist[k] = c
               c += 1
       hanoi(n, 'A', 'B', 'C')
       print()
   except:
       break

Problem D: Towers of Hanoi II

topic description

Use 1, 2, ..., n to represent n plates, which are called plate No. 1, plate No. 2, .... The bigger the number, the bigger the plate. The classic Tower of Hanoi problem often exists as a recursive classic example. Some people may not know the allusion of the Tower of Hanoi problem. The Tower of Hanoi comes from a story in Indian legend. When God created the world, he made three diamond pillars. On one pillar, 64 gold discs were stacked in order of size from bottom to top. God ordered Brahmin to rearrange the discs on another pillar in order of size from below. And it is stipulated that the disk cannot be enlarged on the small disk, and only one disk can be moved between the three pillars at a time. We know that we need to move at least 2^64-1 times. During the moving process, we found that some discs moved more times and some less
. Tell the total number of plates and the plate number, and calculate the number of moves of the plate.

enter

Contains multiple sets of data, first enter T, indicating that there are T sets of data. Each line of data is the number of plates N (1<=N<=60) and plate number k (1<=k<=N).

output

For each set of data, output a number, the minimum number of moves required for disk k to reach the target.

Sample input:
2
60 1
3 1
Sample output:
576460752303423488
4

Plate No. 1 takes 2**(n-1) steps, plate No. 2 takes 2**(n-2) steps, plate No. 3 takes 2**(n-3) steps, ..., just recursively.

def check(x):
    step = 1
    for i in range(1, x+1):
        step *= 2
    return step


t = int(input())
for _ in range(t):
    n, k = map(int, input().split())
    print(check(n-k))
    

Question E: Arranging all letters

topic description

Write a program that uses a recursive algorithm to output the full permutation of all characters in a one-dimensional character array, assuming the characters are all different. For example, the full arrangement of {'a','b','c'} is (a,b,c),
(a,c,b), (b,a,c), (b,c,a), (c,a,b), (c,b,a)

enter

Multiple sets of test cases, each input a positive integer n (0<n<=26).

output

The output starts from a, the full arrangement of n consecutive letters, and each set of output is separated by a space.

Sample input:
1
2
Sample output:
a

what
?

from itertools import *


while True:
    try:
        n = int(input())
        a = [] # 装n个英文字母
        s = 96  # a为97
        for _ in range(n):
            s += 1
            a.append(chr(s))
        for items in permutations(a):  # python中的库函数,返回一个按字典序排列的元组
            for j in items:
                print(j, end='')
            print()
        print()  # 注意输出要求,换行
    except:
        break


Problem F: Nine Array Fractions

topic description

1, 2, 3…9 These nine numbers form a fraction, its value is exactly 1/3, each number is required to appear and can only appear once, how to combine? Write a program to output all combinations.

enter

none

output

Output all the results, if there are more than one, each result occupies one line. The format of the result: xxxx/xxxxx , output in ascending order of molecules.

from itertools import permutations

# 生成所有9个数字的排列
digits = permutations("123456789")

# 遍历所有排列,计算分数值
for d in digits:
    numerator = int("".join(d[:4]))
    denominator = int("".join(d[4:]))
    if numerator*3 == denominator:
        print("{}/{}".format(numerator, denominator))

Question G: High Bridges and Low Bridges

topic description

There is a brain teaser like this: There are two bridges, one high and one low, very close to each other. After two floods, the high bridge was flooded twice, but the low bridge was only flooded once. Why? The answer is: because the low bridge is too low, the water level is still above the low bridge after the first flood recedes, so it is not counted as "flooded twice". For example:
Assume that the heights of the high bridge and the low bridge are 5 and 2 respectively, and the initial water level is 1. The first flood: the water level increases to 6 (both bridges are flooded), and retreats to 2 (the high bridge is no longer flooded, But the low bridge is still flooded)
Second flood: water level raised to 8 (high bridge flooded again), receded to 3.
That's right, word games. The key lies in the meaning of "you". If a bridge is still submerged after a certain flood subsides, it will not be counted as "another" flood when the next flood comes and the water level rises.
Input the height of n bridges and the rising water level ai and receding water level bi of the i-th flood, and count how many bridges have been flooded at least k times. The initial water level is 1, and the rising water level of each flood must be greater than the receding water level of the previous flood.

enter

The input file contains up to 25 sets of test data. The first line of each set of data is three integers n, m,
k (1<=n, m, k<=10 5). The second line contains n integers hi (2<=hi<=10 8), that is, the height of each bridge. Each of the following m lines contains two integers ai and bi (1<=bi<ai<=10^8,
ai>bi-1). The input file should not exceed 5MB.

output

For each set of data, output the number of bridges that have been flooded at least k times.

Sample input:
2 2 2
2 5
6 2
8 3 5
3 2 2 3
4 5 6
5 3
4 2
5 2
Sample output:
Case 1: 1
Case 2: 3

  • Sort the bridges in ascending order of height (for binary optimization)
  • For each flood, check whether each bridge is flooded in order from high to low, and add one if yes. Binary search can be used here to reduce the number of traversals, otherwise the time complexity is too high (because our first step is sorting).
  • Output the number of bridges flooded at least k times.
  • The python version still can't pass (50%) time and memory are exploding, but C++ can pass.

python:

from bisect import *

case = 0
while True:
    try:
        n, m, k = map(int, input().split())
        a = list(map(int, input().split()))  # 每座桥的高度
        a.sort()
        c = []  # 洪水的张水水位和退水水位
        num = [0] * (n+1)  # 桥被淹了多少次
        for _ in range(m):
            x, y = map(int, input().split())
            c.append([x, y])
        t = 0
        for item in c:
            left = bisect_left(a, t+1)  # 由题意可知如果退水位和桥高度一样的话不算淹的,所以加1
            right = bisect_right(a, item[0])
            t = item[1]
            num[left] += 1
            num[right] -= 1
        s = 0
        count = 0
        for i in range(n):
            s += num[i]
            if s >= k:
                count += 1
        case += 1
        print(f"Case {
      
      case}: {
      
      count}")
    except:
        break

C++:

#include <bits/stdc++.h>
using namespace std;
 
int main() {
    
    
    int caseCnt = 0;
    while (true) {
    
    
        int n, m, k;
        if (scanf("%d%d%d", &n, &m, &k) != 3) {
    
    
            break;
        }
        vector<int> a(n);
        for (int i = 0; i < n; i++) {
    
    
            scanf("%d", &a[i]);
        }
        sort(a.begin(), a.end());
        vector<pair<int, int>> c(m);
        for (int i = 0; i < m; i++) {
    
    
            scanf("%d%d", &c[i].first, &c[i].second);
        }
        int t = 0;
        vector<int> num(n + 1);
        for (int i = 0; i < m; i++) {
    
    
            int left = lower_bound(a.begin(), a.end(), t + 1) - a.begin();
            int right = upper_bound(a.begin(), a.end(), c[i].first) - a.begin() - 1;
            t = c[i].second;
            num[left] += 1;
            num[right + 1] -= 1;
        }
        int s = 0, count = 0;
        for (int i = 0; i < n; i++) {
    
    
            s += num[i];
            if (s >= k) {
    
    
                count += 1;
            }
        }
        caseCnt++;
        printf("Case %d: %d\n", caseCnt, count);
    }
    return 0;
}
 

Problem H: Towers of Hanoi III

topic description

"Tower of Hanoi" is a well known ancient game.
Now let's change the question a bit: if there are 4 pillars instead of 3, how many times do you need to move the disk at least to move all the disks from the 1st pillar to the 4th pillar?

For programming convenience, you only need to output the value of this result mod 10000.

enter

This question contains multiple sets of test data, each with a positive integer n. (0<n<=50000)

output

A positive integer representing the minimum number of moves mod 10000 required to move n plates from the 1st pillar to the 4th pillar.

Sample input:
15
Sample output:
129

Find the law (slowly taste)
quote blog: 4 Towers of Hanoi

insert image description here

num = [0] * 50011
num[1] = 1
cnt, s, limit = 0, 2, 2  # 统计个数,前后差值, 个数上限
for i in range(2, 50010):
   cnt += 1
   num[i] = (num[i - 1] + s) % 10000
   if cnt == limit:  # 当cnt=limit时,差值乘2模10000,cnt重置为0,limit加1
       cnt = 0
       limit += 1
       s *= 2
       s %= 10000

while True:
   n = int(input())
   print(num[n])

Summarize

rush and it's over

Guess you like

Origin blog.csdn.net/weixin_62988040/article/details/129559891