2023.10.15日算法练习

题目:P1825B LuoTianyi and the Table

题目链接

https://codeforces.com/problemset/problem/1825/B

题目标签

#greedy #math #difficut1000

题意

现在有n * m个数字,你需要把他们填入表(n行、m列)中,最后按照一数学公式求出表格对应的值,输出最大值。
![[P1825B公式.png]]

讲解

n * m个数字排序,使最大值出现最多次或使最小值出现最多次,即将其放置在左上角。

  1. 最小值:
    我们将最小值放在左上角,最大值放在(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)。
  2. 最大值
    与最小值推理一致,我们给出最终输出的公式:(max - min1) * (n * (m - 1)) + (max - min2) * (n - 1)。
  3. 特殊情况:只有一行
    只有一行,可以让其输出(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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值