题目描述

鸡尾酒的学生丹丹永远分不清减法和求余,他觉得两种运算都是将数字变小,所以差不多。 于是鸡尾酒给了他两道题目来帮助他分清这两种运算。第一道题目是这样的:给定一个包含 𝑛个数字的数组,每次你可以任选两个数字做减法运算,将这两个数字变成一个新数字放回数组,经过 n−1 次操作之后变成一个数字。你的目标是让最终的这一个数字变得尽可能大,请问最大是多少。 当然,这道题只涉及减法,于是鸡尾酒还有一道同样的题(只有加粗的地方不同):给定一个包含 𝑛个数字的数组,每次你可以任选两个数字做求余运算,将这两个数字变成一个新数字放回数组,经过 n−1 次操作之后变成一个数字。你的目标是让最终的这一个数字变得尽可能大,请问最大是多少。

分析: 这道题需要从样例下手,找到规律,根据规律写代码。但是这样只能拿90分,因为还有一种特殊情况:就是当n=1的时候。写代码时记得特判一下。

错因:在写代码的时候,只考虑了求余,没有考虑到减法,导致我只拿了40分。

代码:

/*
样例说明
(1)
输入:        输出: 
5 1           13
1 2 3 4 5
(1) 1-2=-1 (2) -1-4=-5 (3) -5-3=-8 (4) 5--8=13
综合:5-(1-(2+3+4)) = 5-1-(2+3+4) =  5-1+2+3+4+1-1=(1+2+3+4+5)-1-1
由此可知:n个数相减最大值=n个数相加-其中最小的数*2

(2)
输入:          输出: 
3 2             100 
100 400 905
(1) 905%400=105 (2) 100%105=100
综合:100%(905%400) = 100%905%400 = 100%400%905 = 100
由此可知:n个数取余求最大值=n个数中最小的那个

注意:还有一个坑
当n=1的时候,算出来的结果不是最大值,这里要特判一下 

数据范围:
n最多就10^5,开int可以解决 
*/
#include<bits/stdc++.h>
using namespace std;
int n,k;
long long a[100010],sum; 
int main(){
	freopen("divmod.in","r",stdin);
	freopen("divmod.out","w",stdout);
	cin>>n>>k;
	for(int i=0;i<n;i++){
		cin>>a[i];
		if(a[i]) sum+=a[i];
	}
	sort(a,a+n);//排序 找到最小值 
	if(n==1){//注意,这里是个坑!!! 
		cout<<a[0];
		return 0; 
	}
	if(k==1) cout<<sum-a[0]*2;//减法  
	else cout<<a[0];//求余 
		return 0;
	}

0 条评论

目前还没有评论...