助手Christina发明了一种方格取数的新玩法:在n*m的方格棋盘里,每个格子里写一个数。两个人轮流给格子染色,直到所有格子都染了色。在所有格子染色完后,计算双方的分数。对于任意两个相邻(即有公共边)的格子,如果它们都被同一个人染色,那么这个人将得到这两个格子中的数的异或的分数。所有的分数加和计算。

现在,Christina用这个游戏来挑战你,想让你一败涂地,因此她总是采用最优策略使得她的分数尽可能地比你多。为了不输得太惨,你需要知道自己最多比助手多多少分数,或最少比助手少多少分数——也就是你的得分减去助手的得分最大是多少。(先后手由输入给定)

输入

第一行一个正整数T,表示数据组数。

对于每组数据,输入第一行为三个整数n,m,f。其中f为0或1,当f=0,你是先手,当f=1,你是后手。

接着输入n行,每行m个非负整数,表示格子里的数。

输入保证2<=n,m<=400。格子里的数均为不超过int范围的非负整数。

此题有多组数据,数据组数T<=10。

输出

对于每一组数据,输出一行一个整数:你的得分减去助手的得分的最大值。

SOURCE:codeforces

输出时每行末尾的多余空格,不影响答案正确性

样例输入

1
3 3 0
1 2 3
4 5 6
7 8 9

样例输出

11

题目来源

ACM训练联盟周赛

分析:这题目的关键是怎么选择下一步。

题目求分数的过程中,如果有相邻的分数则两分数需异或,所以每个点的分数并不是最后可以用来算总分的分数。

他们的实际分数应该是这个点的分数和相邻所有点分数的异或和

然后我们根据所有的异或和相隔着一人取一个分数就可以得到每个人所能得到的最大分数

因为实际运算的结果中并不能取到结果点的所有相邻点,只能取到一半,所以在计算结果时还要再除以二

#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define debug(a) cout << #a << " " << a << endl
using namespace std;
const int maxn = 4*1e2 + 10;
const int mod = 1e9 + 7;
typedef long long ll;
ll mapn[maxn][maxn], a[maxn*maxn];
ll dx[] = { 1, -1, 0, 0 }, dy[] = { 0, 0, 1, -1 };
bool cmp( ll x, ll y ) {
return x > y;
}
int main() {
ll t;
cin >> t;
while( t -- ) {
ll n, m, f;
memset( a, 0, sizeof(a) );
cin >> n >> m >> f;
for( ll i = 0; i < n; i ++ ) {
for( ll j = 0; j < m; j ++ ) {
cin >> mapn[i][j];
}
}
ll cnt = 0;
for( ll i = 0; i < n; i ++ ) {
for( ll j = 0; j < m; j ++ ) {
a[cnt] = 0;
for( ll k = 0; k < 4; k ++ ) {
ll x = i + dx[k];
ll y = j + dy[k];
if( x >= 0 && x < n && y >= 0 && y < m ) {
a[cnt] += (mapn[i][j]^mapn[x][y]);
}
}
cnt ++;
//cout << a[cnt-1] << " ";
}
//cout << endl;
}
sort( a, a + cnt, cmp );
ll sum1 = 0, sum2 = 0;
for( ll i = 0; i < cnt; i ++ ) {
if( i&1 ) {
sum2 += a[i];
} else {
sum1 += a[i];
}
}
//因为要取到相邻的所有点的时候才能得到结果,然而在我们实际的运算
//结果中只取到了这些结果点的一半相邻点,所以要除以二
if( !f ) {
cout << ( sum1 - sum2 ) / 2 << endl;
} else {
cout << ( sum2 - sum1 ) / 2 << endl;
}
}
return 0;
}

  

最新文章

  1. 【数据挖掘】朴素贝叶斯算法计算ROC曲线的面积
  2. 线程池深入(li)
  3. Invalidate,Update与Refresh的区别
  4. sql编程小结
  5. 淘宝(阿里百川)手机客户端开发日记第十一篇 JSP+Servlet
  6. 【ubuntu】首选项和应用程序命令(preference &amp; application)
  7. 在C#使用文件监控对象FileSystemWatcher的几种方案
  8. 每天一道LeetCode--371. Sum of Two Integers
  9. allegro 16.6 空心焊盘的制作
  10. c++模板实例化的一个例子
  11. Muduo源码库研究(笔记汇总)
  12. [转] HTML中调用JavaScript的几种情况和规范写法
  13. linux工作中遇到的问题总结---更新中
  14. 【转】JAVA处理线程超时
  15. Scala 编码习惯
  16. 我对C#的认知。
  17. Tensorflow图像处理以及数据读取
  18. Allegro PCB Design GXL (legacy) 使用slide推挤走线,走线的宽度就发生改变的原因
  19. win7 x64安装TensorFlow
  20. 20155205 2016-2017-2《Java程序设计》课程总结

热门文章

  1. PHP编码风格规范
  2. mysql中left join right join inner join用法分析
  3. Linux基础进程管理
  4. kubeproxy源码分析
  5. cogs 1254. 最难的任务 Dijkstra + 重边处理
  6. Redis回顾
  7. 监控JVM
  8. 上传文件时 重新载入页面以获取源代码 http://*/upload.php
  9. csdn论坛页抓取
  10. c#滑窗缓存