[CF1447B]Numbers Box
题目传送门
一道思路十分好想的 水题 贪心题。
题目大意:
有 \(t\) 次提问,每次提问输入两个数 \(m,n\) 表示行和列,输入 \(a_{ij}\) 表示第 \(i\) 行 \(j\) 列中的数,每次可将两个相邻的数乘 \({-1}\) 使最终矩阵中所有数相加的和最大。
思路:
要使矩阵中所有数之和最大,正数一定要越多越好 ,我们可以将相邻的两个负数都变成正数。
不需要相邻的数才可以变,我们可以选矩阵中任意两个数进行改变,这样一来,我们可以将矩阵中的负数变成 \(n%2\) 个,如果还剩一个负数,还可以将负数随意替换到每一个位置,当然,我们要将它替换到绝对值最小的数上。
实现:
-
用 \(ans\) 存储每一个输进来的 \(a_{ij}\) 的绝对值:
ans+=abs(a);
-
用 \(gs\) 记录矩阵中负数的个数:
if(a<0) gs++;
-
用 \(mn\) 存储 \(a_{ij}\) 的最小绝对值:
mn=min(mn,abs(a));
-
如果 \(gs\) 为偶数,直接输出 \(ans\) (全部都变正数):
if(gs%2==0) cout<<ans<<endl;
-
否则输出 \(ans-mn \times 2\) (还剩一个负数):
else cout<<ans-mn*2<<endl;
AC code:
#include<bits/stdc++.h>
using namespace std;
int t,n,m;
int mian()
{
cin>>t;
while(t--) //询问t次
{
int gs=0,ans=0,mn=105; //初始化
cin>>n>>m;
for(int i=1,a;i<=n;i++) //循环整个矩阵
for(int j=1;j<=m;j++)
{
cin>>a;
ans+=abs(a); //ans加上a的绝对值
if(a<0)
gs++; //记录负数个数
mn=min(mn,abs(a)); //记录最小的绝对值
}
if(gs%2==0) //全部变正数
cout<<ans<<endl;
else //还剩一个负数
cout<<ans-mn*2<<endl; //答案中一个数从正变负,减两遍
}
return 0;
}
标签:Box,CF1447B,int,mn,矩阵,负数,Numbers,ans,绝对值
From: https://www.cnblogs.com/Hyper-zero/p/18377874