首页 > 试题广场 >

获得最多的奖金

[编程题]获得最多的奖金
  • 热度指数:27554 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 128M,其他语言256M
  • 算法知识视频讲解
小明在越南旅游,参加了当地的娱乐活动。小明运气很好,拿到了大奖, 到了最后的拿奖金环节。小明发现桌子上放着一列红包,每个红包上写着奖金数额。
现在主持人给要求小明在这一列红包之间“切”2刀,将这一列红包“切”成3组,并且第一组的奖金之和等于最后一组奖金和(允许任意一组的红包集合是空)。最终第一组红包的奖金之和就是小明能拿到的总奖金。小明想知道最多能拿到的奖金是多少,你能帮他算算吗。

举例解释:桌子上放了红包  1, 2, 3, 4, 7, 10。小明在“4,7”之间、“7,10” 之间各切一刀,将红包分成3组 [1, 2, 3, 4]   [7]   [10],其中第一组奖金之和=第三组奖金之和=10,所以小明可以拿到10越南盾。

数据范围:红包数量满足 ,红包金额满足

输入描述:
第一行包含一个正整数n,表示有多少个红包。

第二行包含n个正整数d[i],表示每个红包包含的奖金数额。


输出描述:
小明可以拿到的总奖金
示例1

输入

5
1 3 1 1 4

输出

5

说明

[1,3,1]  [ ]   [1,4] ,其中第一组奖金和是5,等于第三组奖金和。所以小明可以拿到5越南盾 
示例2

输入

5
1 3 2 1 4

输出

4

说明

[1,3]   [2,1]  [4],小明可以拿到4越南盾 
示例3

输入

3
4 1 2

输出

0

说明

[ ]  [4, 1, 2] [ ] ,小明没办法,为了保证第一组第三组相等,只能都分成空的。所以小明只能拿到0越南盾。 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Scanner;

/**
  好多人用的双指针,感觉这题前缀和直接出答案 
*/
public class Main {

    static int n, N = 200010;
    static long max;
    static long[] s = new long[N];
    static HashMap<Long, Integer> map = new HashMap<>();
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        n = Integer.parseInt(bf.readLine());
        String[] arr = bf.readLine().split(" ");
        for(int i = 1; i <= n; i ++){
            s[i] += s[i - 1] + Integer.parseInt(arr[i - 1]);
            map.put(s[i], i);
        }

        for(int i = n; i >= 1; i --){
            long cur = s[n] - s[i - 1];
            if(map.containsKey(cur) && map.get(cur) < i && cur > max)
                  max = cur;
        }
        System.out.println(max);
    }

}




发表于 2021-08-10 10:21:07 回复(0)
双指针的思路,但是做题太马虎,最初把加和的类型定义成了int,一直报无法通过用例,填坑。。

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt();
        long[] b = new long[a];
        for(int r=0; r<a; r++){
            b[r] = sc.nextInt();
        }
        int i = 0;
        int j = a - 1;
        long left = b[i];
        long right = b[j];
        long result = 0;
        while(i<j){
            if (left<right){
                i++;
                left = left + b[i];
            }else if (left > right){
                j--;
                right = right + b[j];
            }else{
                result = left;
                i++;
                j--;
                left = left + b[i];
                right = right + b[j];
            }
        }
        System.out.println(result);
    }
}
发表于 2020-08-03 15:33:34 回复(1)

Java;双指针;前缀和算法

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        long[] d = new long[n];
        long[] sum = new long[n];
        //计算前缀和,包含本身
        for(int i=0;i<n;i++){
            d[i] = sc.nextInt();
            if(i == 0)
                sum[i] = d[i];
            else
                sum[i] = sum[i-1] + d[i];
        }
        //双指针,计算最大奖金和
        long max = 0;
        int start = 0,end = n-1;
        while(start < end){
            if(sum[start] < (sum[n-1] - sum[end-1])){
                start++;
            }
            else if(sum[start] == (sum[n-1] - sum[end-1])){
                max = Math.max(max,sum[start]);
                start++;
                end--;
            }
            else
                end--;
        }
        System.out.println(max);
    }
}
发表于 2020-06-01 10:06:13 回复(0)
import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            //数据的个数
            int n = Integer.valueOf(sc.nextLine());
            String[] str = sc.nextLine().split(" ");
            //数据数组
            int[] nums = new int[n];
            long max = 0;
            for(int i =0;i<n;i++){
                nums[i]=Integer.valueOf(str[i]);
            }
            max = select(nums,0,nums.length-1);
            System.out.println(max);
        }
    }
    //双指针
    public static long select(int[] nums,int low,int high){
        long max = 0;
        int left = 0;
        int right = 0;
        while(low<=high){
            if((nums[low]+left)<(nums[high]+right)){
                left +=nums[low];
                low++;
            }else if((nums[low]+left)>(nums[high]+right)){
                right+=nums[high];
                high--;
            }else{
                left += nums[low];
                max += left;
                low++;
                high--;
                left = 0;
                right = 0;
            }
        }
        return max;
    }
}
Java写的双指针移动取值累加法
发表于 2020-05-21 12:00:23 回复(0)
import java.util.*;
public class Main{
    //思路:
    //1.定义左指针跟右指针,分别指向第一个红包和最后一个红包
    //2.左指针指向数据和 > 右指针指向数据和,左指针++;
    //3.左指针指向数据和 < 右指针指向数据和,右指针--;
    //4.左指针指向数据和 = 右指针指向数据和,左指针++,右指针--;
    //约束条件是左指针 < 右指针。
    //需要注意的是所有求和的值都要设为long型,会超过int最大范围。
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();//红包个数
        int[] d = new int[n];//每个红包奖金数额
        for(int i = 0; i < n; i++){
            d[i] = sc.nextInt();
        }
        int left = 0;
        long leftSum = d[left];
        int right = n - 1;
        long rightSum = d[right];
        long max = 0;
        while(left < right){
            if(leftSum < rightSum){
                left++;
                leftSum += d[left];
            }
            if(leftSum > rightSum){
                right--;
                rightSum += d[right];
            }
            if(leftSum == rightSum){
                max = leftSum;
                left++;
                right--;
                leftSum += d[left];
                rightSum += d[right];
            }
        }
        System.out.println(max);
    }
}

发表于 2019-10-31 20:00:45 回复(0)
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        long[] a = new long[n];
        for (int i = 0; i < n; i++) {
            a[i] = input.nextLong();
        }
        long ret = 0L;

        int left = 0;
        int right = n-1;
        int res = 0;
        
        long al = a[left];
        long ar = a[right];
        
        while(left<right){
            if(al<ar){
                left++;
                al+=a[left];
            }else if(al>ar){
                right--;
                ar+=a[right];
                
            }else if(al==ar){
                res = left;
                ret = al;
                left++;
                al+=a[left];
                right--;
                ar+=a[right];
                
            }
        }
        long ret1 = 0L;
        for(int i = 0;i<=res;i++){
            ret1 += a[i];
        }
        if(ret == ret1){
            System.out.println(ret1);
        }else{
            System.out.println("no");
        }
        
    }
}

这段代码通过率为88.89%,在大数组测试样例的时候,会出现ret和ret1不相同的情况,请问大家这段代码有什么问题
发表于 2019-10-22 16:23:29 回复(1)
双指针的做法
左右各一个index,左大右移,右大左移,相同更新max并同时移动
注意用long存结果
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        long[] arr = new long[n];
        for (int i = 0; i < n; i++) {
            arr[i] = sc.nextLong();
        }
        int left = 0;
        long lsum = arr[left];
        int right = n-1;
        long rsum = arr[right];
        long sum = 0L;
        while (left<right){
            if (lsum==rsum){
                left++;right--;
                sum = lsum;
                lsum+=arr[left];
                rsum+=arr[right];
            }else if (lsum<rsum){
                left++;
                lsum+=arr[left];
            }else {
                right--;
                rsum+=arr[right];
            }
        }
        System.out.println(sum);
    }
}


发表于 2019-10-07 00:02:18 回复(0)
import java.util.*;
public class Main{
    public static void main(String [] args)
    {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int [] money = new int[n];
        for(int i=0; i<n; i++)
        {
            money[i] = sc.nextInt();
        }
        long value = 0;
        long left = money[0];
        long right = money[n-1];
        int lin = 0;
        int rin = n-1;
        //这里要做的事情就是移动滑块
        while(lin >= 0 && rin < n && lin<rin )
        {
            if(left < right)
            {
                lin++;
                left += money[lin];
            }
            if(left > right)
            {
                rin--;
                right += money[rin];
            }
            if(left == right)
            {
                 value = left;
                lin++;
                rin--;
                left += money[lin];
                right += money[rin];
               
            }
        }
        
        System.out.print(value);
            
    }
}
发表于 2019-09-05 17:45:59 回复(0)
/*
使用low和high分别从前到尾扫描,若前面的和和后面部分的和相等就标记它们的值,遇到大的就更新max
直到low和high相等。
*/  import java.util.Scanner;
public class Main{
        public static void main(String[] args){
                Scanner sc = new Scanner(System.in);
                int n = sc.nextInt();
                long[] arr = new long[n];
                for(int i=0;i<n;i++)
                        arr[i]=sc.nextLong();
                int low=0,high=n-1;
                long max=0,lowSum=arr[low],highSum=arr[high];
                while(low<=high){
                        if(lowSum>highSum)
                                highSum+=arr[--high];
                        else if(lowSum<highSum)
                                lowSum+=arr[++low];
                        else{
                                max=lowSum;
                                lowSum+=arr[++low];
                                highSum+=arr[--high];
                        }
                }
                System.out.println(max);
        }
}

发表于 2019-08-22 23:29:10 回复(0)