#736. 徐老师的纸牌游戏

题目:
吃完年夜饭,亲戚们总是要坐下打打牌,打打麻将。

而徐老师不会打牌也不会打麻将,没有办法加入群聊,只能一个人默默的躲在角落画圈圈

聪明的徐老师想要给自己找点游戏玩打发时间,她在手机上找到了一种纸牌游戏

这个纸牌游戏一开始有一个 n * mn∗m 的矩阵,矩阵的每个单元上都放着一张带有点数的纸牌,有的纸牌正面朝上,有的纸牌背面朝上

游戏把正面朝上的牌看做正数,把背面朝上的牌看做负数,那么就得到了一个有正有负的数字矩阵

而游戏规则是这样的,每次可以选择两张相邻的纸牌,并同时翻转它们,游戏里一张牌只和它上下左右四张牌相邻

例如有两张牌的是 1,-21,−2 ,同时翻转它们会变成 -1,2−1,2

而游戏的最终得分是将所有点数相加的和,现在徐老师想知道如果操作次数无限,最多可以获得多少分

输入格式


输入第一行包含一个正整数 TT 表示共有 TT 组测试数据
对于每组测试数据:
输入第一行包含两个整数 n,mn,m,表示矩阵大小
接下来 nn 行,每行包含 mm 个整数 a_{i,j}ai,j​ 分别表示第 ii 行第 jj 列的这张牌,正数表示正面朝上,负数表示背面朝上


对于 40\%40% 的数据,T \leq 10, 1 \leq n,m,a_i \leq 10T≤10,1≤n,m,ai​≤10

对于 100\%100% 的数据,T \leq 10, 1 \leq n,m \leq 500, -100 \leq a_i \leq 100T≤10,1≤n,m≤500,−100≤ai​≤100

输出格式


对于每组测试数据输出一个整数,表示最多能获得的分数

样例

输入数据 1

2
2 2
-2 2
-2 2
3 3
-2 -2 -2
-2 0 -2
-2 -2 -2

输出数据 1

8
16

这道题考的是思维。

思路:从题目可以看出

如果2个数分别为a和b

1.a为负数,b为负数,那么操作之后a,b就都变成正数了

2.a为负数,b为正数,那么操作之后a变成正数,b就变成负数了

3.a为正数,b为负数,那么操作之后a变成负数,b就变成正数了

4.a为正数,b为正数,那么操作之后a,b就都变成负数了

通过题意可知,如果出现第4种情况那么是不需要操作的,因为如果操作了就不能使最后的总和最大

那么题目在2,3种情况中可以看成负号在转移位置

那么有两种情况

{

1.负数有偶数个:那么就可以根据2,3的操作把负数弄到一块,在用1的操作抵消负号

2.负数有奇数给:那么先用上面的操作,再剩余一个负号(注意,这个负号必须要是矩阵中的最小值,这样才能使总和最大!)

}

综上所述,代码如下:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
ll k,m,n,r,t,x,y,ans,cnt,len,res,sum,tmp,a[510][510];
int main()
{
  cin>>t;
  while(t--)
  {
    cnt = 0;
    sum = 0;
    tmp = inf;
    cin>>n>>m;
    for(int i = 1; i <= n; i++)
    {
      for(int j = 1; j <= m; j++)
      {
        cin>>a[i][j];
        if(a[i][j] < 0)
        {
          cnt++;
        }
        sum += abs(a[i][j]);
        tmp = min(tmp,abs(a[i][j]));
      }
    }
    if(cnt % 2 != 0) sum -= 2 * tmp;
    cout<<sum<<endl;
  }
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值