Hihocoder-1286 子矩阵求和
来源:互联网 发布:淘宝秒杀助手官方下载 编辑:程序博客网 时间:2024/06/06 04:19
解题思路:
看到这个题目的时候是很懵逼的= =矩阵是无限的
但是其实没那么刚,只需要巧妙的转换下就可以得到结果。
对于矩阵:
1 1 1 1 1 1 1 11 2 2 2 2 2 2 21 2 3 3 3 3 3 31 2 3 4 4 4 4 41 2 3 4 5 5 5 51 2 3 4 5 6 6 61 2 3 4 5 6 7 71 2 3 4 5 6 7 8对于这样的矩阵,我们能看到两个规律:
用s[i][j]表示左上角左边为(i, j)的子矩阵和
1.对于要求的N*M的子矩阵,当行数超过M后,s[i][j] = s[i+1][j](i >= M),当列数超过N的时候,s[i][j] = s[i][j+1](j >= N)
2.s[i][j] + x * N * M = s[i+x][j+x]
所以这题的做法就出来了,只需要枚举第一行和第一列,对于每个位置,求(s[i][j] + x*N*M) mod k = 0的最小x,这个时候很自然的想到扩展欧几里得算法。所以求一发就解出来了。
代码:
#include <set>#include <map>#include <cmath>#include <queue>#include <stack>#include <cstdio>#include <vector>#include <string>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>#include <functional>using namespace std;typedef long long LL;const LL inf = 1e18 + 5;LL x, y, ans_x, ans_y;LL extend_gcd(LL a, LL b, LL& x, LL &y) { if ( b == 0 ) { x = 1; y = 0; return a; } LL ans = extend_gcd( b, a % b, y, x ); y -= a / b * x; return ans;}LL solve( LL n, LL m, LL cur, LL sum ) { LL i = n + cur - 1; if ( i > m ) sum += (m + 1) * m / 2; else{ sum += (i + 1) * i / 2; sum += i * (m - i); } if ( cur - 1 > m ) sum -= (m + 1) * m / 2; else { sum -= cur * (cur - 1) / 2; sum -= (cur - 1) * (m - cur + 1); } return sum;}bool judge( LL a, LL b, LL c, LL d, LL base1, LL base2 ) { if ( (c % d) == 0 ) { a /= d; b /= d; c /= d; LL tmp = ((x % b) * (c % b)) % b; while(tmp < 0) tmp += b >= 0 ? b : -b; LL tt = tmp * 2 + base1 + base2; if ( tt < ans_x + ans_y || (tt == ans_x + ans_y && tmp + base1 < ans_x) || (tt == ans_x + ans_y && tmp + base1 == ans_x && tmp + base2 < ans_y) ) { ans_x = base1 + tmp; ans_y = base2 + tmp; } return true; } return false;}int main() { LL q, n, m, k; cin >> q; while(q--) { LL init = 0; cin >> n >> m >> k; for ( LL i = 1; i <= n; ++i ) { if ( i > m ) init += (m + 1) * m / 2; else { init += (i + 1) * i / 2; init += i * (m - i); } } ans_x = ans_y = inf; bool flag = false; LL A = -n * m, B = k, C = init; LL D = extend_gcd(A, B, x, y); flag |= judge(A, B, C, D, 1, 1); LL sum = init; for ( LL i = 2; i <= n; ++i ) { sum = solve(m, n, i, sum); flag |= judge(A, B, sum, D, 1, i); } sum = init; for ( LL i = 2; i <= m; ++i ) { sum = solve(n, m, i, sum); flag |= judge(A, B, sum, D, i, 1); } if ( !flag ) cout << "-1" << endl; else cout << ans_x << " " << ans_y << endl; } return 0;}
0 0
- Hihocoder-1286 子矩阵求和
- #1286 : 子矩阵求和
- 最大子矩阵求和
- hihocoder #1502 : 最大子矩阵
- 最大子矩阵求和问题
- 求和最大的子矩阵
- hihocoder 1580(最大子矩阵变形)
- 二维树状数组--子矩阵求和
- hdu 1081 最大子矩阵求和问题
- 二维数组最大子矩阵的求和
- 给定一个矩阵,求和最大的子矩阵
- 【矩阵二维或三维dp】最大子矩阵,子矩阵快速求和(用到最大直方图)
- hihocoder 1372 平方求和
- hdu1081 To The Max_最大子矩阵求和问题
- 最大子矩阵求和 NYOJ 104 && 372 && HDU 1081
- NOI 1101. 子矩阵求和(高效方法,解决超时问题)
- 矩阵求和
- 矩阵求和
- leveldb源码剖析---缓存系统
- ubuntu16.04配置ssh免密码登陆
- 第三十九将项目八 回文日
- 查看Linux版本信息
- Android事件分发机制源码畅游解析(Activity篇)
- Hihocoder-1286 子矩阵求和
- 一阶RC低通滤波
- 开启 控制文件自动备份下,参数文件、控制文件全部丢失恢复
- 0424
- Android中关于接口回调
- 安卓沉浸式状态栏延生与透明设置
- RobotFramework RIDE run报‘class Importerr ,no module name rebot’错误的解决方法
- elasticsearch-head安装及启动
- 51nod_1008 N的阶乘 mod P