"Algorithm Competition·Quick 300 Questions" One question per day: "Squirrel and Chestnut"

" Algorithm Competition: 300 Quick Questions " will be published in 2024 and is an auxiliary exercise book for "Algorithm Competition" .
All questions are placed in the self-built OJ New Online Judge .
Codes are given in three languages: C/C++, Java, and Python. The topics are mainly mid- to low-level topics and are suitable for entry-level and advanced students.


" Squirrel and Chestnut ", link: http://oj.ecustacm.cn/problem.php?id=1852

Question description

[Problem Description] There are m chestnut trees, and n squirrels are waiting for the chestnuts to fall.
   The first chestnut of the i-th tree is at t[i], and one drops every p[i] seconds thereafter.
   Now the squirrels hope to eventually get k chestnuts, and each squirrel will choose a chestnut tree to wait for.
   The time it takes for the squirrel to move to each tree is not considered, only the waiting time.
   Request the minimum waiting time under the optimal situation, that is, the squirrel chooses n chestnut trees under the optimal situation to wait, and what is the minimum waiting time.
[Input format] The first line is positive integers m, n, k. 1≤n≤m≤10000, 1≤k≤10^7.
   The second line contains m integers representing t[i].
   The third line contains m integers representing p[i], 1≤t[i], p[i]≤100.
[Output format] Output a number to represent the answer.
【Input sample】

样例13 2 5
5 1 2
1 2 1

样例23 2 5
5 1 2
1 1 1

【Output sample】

样例14

样例23

answer

   This is a very straightforward two-part question. The longer the waiting time, the more chestnuts will be dropped, so the number of chestnuts corresponding to the waiting time is monotonically increasing, and the dichotomy method can be used. Guess a minimum waiting time x and use the bisection method to find x.
   Use the check(x) function to determine whether more than k chestnuts have been dropped at time x. First, calculate the total number of chestnuts dropped by m trees in x seconds. If the total number of chestnuts is less than k, return false; if there are more than k, sort the chestnuts dropped by m trees and select the top n ones to compare with k.
[Key point] Two points.

C++ code

#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
int t[N], p[N];
int num[N];
int n, m, k;
bool check(int x){
    
    
    for(int i = 1; i <= m; i++)  {
    
    
        if(x >= t[i])  num[i] = (x - t[i]) / p[i] + 1;
        else           num[i] = 0;
    }
    long long sum = 0;
    sort(num + 1, num + 1 + m, greater<int>());  //从大到小排序
    for(int i=1; i<=n && i<=m; i++)  sum += num[i];
    return sum >= k;
}
int main(){
    
    
    cin >> m >> n >> k;
    if(n > m)  n = m;
    for(int i=1; i<=m; i++)  cin >> t[i];
    for(int i=1; i<=m; i++)  cin >> p[i];
    int L=0, R=1e9, ans=0;
    while(L <= R){
    
    
        int mid = (L + R) >> 1;
        if(check(mid))   ans = mid, R = mid - 1;
        else             L = mid + 1;
    }
    cout<<ans<<endl;
    return 0;
}

Java code

import java.util.*;
public class Main {
    
    
    static int[] t = new int[10010];
    static int[] p = new int[10010];
    static int[] num = new int[10010];
    static int n, m, k;
    public static boolean check(int x) {
    
    
        for (int i = 1; i <= m; i++) {
    
    
            if (x >= t[i]) num[i] = (x - t[i]) / p[i] + 1;
            else num[i] = 0;
        }
        long sum = 0;
        Arrays.sort(num, 1, m + 1);
        for (int i=1; i<=n && i<=m; i++) sum += num[m - i + 1];
        return sum >= k;
    }
    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        m = sc.nextInt();
        n = sc.nextInt();
        k = sc.nextInt();
        if (n > m) n = m;
        for (int i = 1; i <= m; i++) t[i] = sc.nextInt();
        for (int i = 1; i <= m; i++) p[i] = sc.nextInt();
        int L = 0, R = 1000000000, ans = 0;
        while (L <= R) {
    
    
            int mid = (L + R) >> 1;
            if (check(mid)) {
    
     ans = mid;  R = mid - 1; } 
            else  L = mid + 1;            
        }
        System.out.println(ans);
        sc.close();
    }
}

Python code

t = [0] * (10010)
p = [0] * (10010)
num = [0] * (10010)
def check(x):
    for i in range(1, m + 1):
        if x >= t[i]:  num[i] = (x - t[i]) // p[i] + 1
        else:          num[i] = 0
    num.sort(reverse=True)
    sum = 0
    for i in range(1, n+1 if n<=m else m+1):   sum += num[i]
    return sum >= k
m, n, k = map(int, input().split())
t[1:] = [int(x) for x in input().split()]
p[1:] = [int(x) for x in input().split()]
L, R, ans = 0, 1000000000, 0
while L <= R:
    mid = (L + R) // 2
    if check(mid):
            ans = mid
            R = mid - 1
    else:   L = mid + 1
print(ans)

Guess you like

Origin blog.csdn.net/weixin_43914593/article/details/132566038