题目:P1825B LuoTianyi and the Table
题目链接
https://codeforces.com/problemset/problem/1825/B
题目标签
#greedy #math #difficut1000
题意
现在有n * m个数字,你需要把他们填入表(n行、m列)中,最后按照一数学公式求出表格对应的值,输出最大值。
![[P1825B公式.png]]
讲解
n * m个数字排序,使最大值出现最多次或使最小值出现最多次,即将其放置在左上角。
- 最小值:
我们将最小值放在左上角,最大值放在(1,2)或(2,1),这样才能使最大值出现最多次。那到底放在哪里呢?我们需要讨论一下,放在(1,2) max可以出现(m - 1) * n次;放在(2,1) max可以出现(n - 1) * m次。如果n > m,便将其放在(2,1)上,否则放在(1,2)上。我们可以用swap使得n < m一定成立即可,因为只是翻转,不会影响最终结果。那么,我们最终输出的公式为:(max1 - min) * (n * (m - 1)) + (max2 - min) * (n - 1)。 - 最大值
与最小值推理一致,我们给出最终输出的公式:(max - min1) * (n * (m - 1)) + (max - min2) * (n - 1)。 - 特殊情况:只有一行
只有一行,可以让其输出(max - min) * (m - 1)
题解
#include<bits/stdc++.h>
using namespace std;
#define ll long long
void solve(){
int n,m;
cin>>n>>m;
int a[10010] = {0};
for(int i = 1;i <= n * m;i++){
cin>>a[i];//可以负数
}
sort(a + 1,a + n * m + 1);
if(n > m) swap(n,m);
if(n == 1)
cout<<(m - 1) * (a[n * m] - a[1])<<endl;
else{
ll ans1=(n*m-1)*(a[n*m])-a[1]*(n*(m-1))-a[2]*(n-1);
ll ans2=a[n*m]*(n*(m-1))+a[n*m-1]*(n-1)-a[1]*(n*m-1);
cout<<max(ans1,ans2)<<endl;
}
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}