Lanqiao Cup 2023 14th Provincial Competition Real Questions-Maigua--C Language Question Solution

Table of contents

Lanqiao Cup 2023 14th Provincial Competition Real Questions-Maigua

Question description

Input format

Output format

Sample input

Sample output

hint

[Analysis of ideas]

【Code】


Lanqiao Cup 2023 14th Provincial Competition Real Questions-Maigua

Time limit: 3s Memory limit: 320MB Submits: 796 Resolves: 69

Question description

Xiao Lan is buying melons at a melon stall. There are n melons on the melon stall, and the weight of each melon is Ai.

Little Blue Knife is so good that he can split any melon into two parts of exactly equal weight, but he can only chop each melon once.

Xiaolan hopes that the sum of the weights of the melons she wants to buy is exactly m.

Please ask Xiao Lan at least how many melons he has to split to buy a melon with a weight of exactly m. If Xiaolan cannot get a melon with a total weight of exactly m no matter what, please output −1.

Input format

The first line of input contains two integers n and m, separated by a space, which respectively represent the number of melons and the total weight of the melons that Xiaolan wants to buy.

The second line contains n integers Ai, separated by a space between adjacent integers, representing the weight of each melon respectively.

Output format

One line of output contains an integer representing the answer.

Sample input

copy

3 10
1 3 13

Sample output

copy

2

hint

For 20% of the evaluation use cases, ∑n≤10;

For 60% of the evaluation cases, ∑n≤20;

For all evaluation cases, 1 ≤ n ≤ 30, 1 ≤ Ai ≤ 109, 1 ≤ m ≤ 10^9

[Analysis of ideas]

This question is a very simple list of recursive possibilities, but there are three situations in each recursion, so the time complexity is O(3^N). The time complexity is too high, so it is necessary to get rid of those complete recursions during the recursion process. Impossible solutions reduce complexity.

【Code】

#include<stdio.h>
int n = 0, m = 0, nums[30], min = 100;
long suf[31];
int dfs(int i, double sum, int c) {
	if (c >= min) return 100;         // 劈瓜的次数大于等于最小值,即使能满足要求m也没有意义,因为它不是最小的
	if (sum == m) {
        min = c;
        return c;
    }
    if (sum > m) return 100;          // 如果当前sum大于m,即可提前结束
	if (i == n) {
        return 100; //此时已经使用了所有西瓜,也无法满足,直接排除掉
   }
    if (suf[i] + sum < m) return 100; // 如果当前sum加上剩余所有值都小于m,即可提前结束
    int a = dfs(i + 1, sum + nums[i], c); // 全拿走 
    int b = dfs(i + 1, sum + (nums[i] / 2.0), c + 1); // 拿走一半 
    int f = dfs(i + 1, sum, c);  // 不拿走 
	int k = mins(b, f);
    return mins(a, k);
}
int mins(int a, int b){
	return a > b? b :a;
}
int main(){
        scanf("%d %d", &n, &m);
        int i = 0;
        for (i = 0; i < n; i++) {
            scanf("%d", &nums[i]);
        }
        for (i = n - 1; i >= 0; i--) {
            suf[i] = suf[i + 1] + nums[i];
        }
        int m = dfs(0, 0, 0);
        if (m == 100)
            printf("-1");
        else{
        	printf("%d\n",m);
		}
        return 0;
}

Guess you like

Origin blog.csdn.net/weixin_73936404/article/details/132994654