CF1873B题解

思路

我们可以定义我们将要加一的数字为 aka_k,定义我们改变 aka_k 前的积是 ansans 那么加一之后的答案应为 ans÷ak×(ak+1)ans \div a_k \times (a_k+1)。化简得 ans+ansakans+\dfrac{ans}{a_k},其中 ansans 是确定的,所以 aka_k 最小时,原式的值最大。

实现

用一个变量 minnminn 记录最小值,用 bb 统计 00 出现的次数(用于特判),
ansans 的意义和上文相同。

特判内容:由于 ans÷ak×(ak+1)ans \div a_k \times (a_k+1) 中除数 aka_k 可能为 00,导致 RE。

理论存在,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include<iostream>
#define int long long//数据爆 int
using namespace std;
int t,n,minn,ans,b;
int a[10];
signed main(){
cin>>t;
while(t--){
cin>>n;
minn=0x7fffffff;
ans=1; //多测初始化
b=0;
for(int i=1;i<=n;++i){
cin>>a[i];
minn=min(minn,a[i]);
if(a[i]==0){
++b;
continue;//避免 ans 变成 0
}
ans*=a[i];
}
if(b>1){//如果 0 多于一个,那结果就只能是 0
cout<<"0\n";
continue;
}
if(b)//由于把 0 变成 1,所以结果仍为 ans
goto end;//这个语句的作用是跳过下一行代码
ans=ans*(minn+1)/minn;
end:
cout<<ans<<endl;
}
}