1 条题解
-
0
题意:用两条线将矩阵切成三部分, 两天直线可以平行也可以垂直, 如果垂直的话有一条就是射线(要不然变成四部分了)
思路:情况不多 暴力枚举。。。。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll inf = 0x7fffffffffffffff; ll minn; int n, m; ll dp[505][505]; int mapn[505][505]; inline ll abs(ll a){ return a >= 0 ? a : -a; } void Init() //初始化,求(1, 1)到(i,k)矩阵的和 { for(int i = 0; i <= n || i <= m; i++){ dp[i][0] = dp[0][i] = 0; } for(int i = 1; i <= n; i++){ for(int k = 1; k <= m; k++){ dp[i][k] =dp[i-1][k] + dp[i][k-1] - dp[i-1][k-1] + mapn[i][k]; } } } inline ll fun(int up, int dw, int lf, int rg) // 求和 { ll sum = 0; sum += dp[dw][rg] + dp[up-1][lf-1] - dp[up-1][rg] - dp[dw][lf-1]; return sum; } inline void fuck(ll sum1, ll sum2, ll sum3) { ll sum = abs(sum1 - sum2) + abs(sum1 - sum3) + abs(sum2 - sum3); if(sum < minn) minn = sum; } int main() { while(scanf("%d%d", &n, &m) && (m || n)){ for(int i = 1; i <= n; i++){ for(int k = 1; k <= m; k++){ scanf("%d", &mapn[i][k]); } } Init(); minn = inf; for(int i = 1; i < n; i++){ //垂直情况 for(int k = 1; k < m; k++){ ll sum1 = fun(1, i, 1, k); ll sum2 = fun(1, i, k+1, m); ll sum3 = fun(i+1, n, 1, k); ll sum4 = fun(i+1, n, k+1, m); fuck(sum1+sum2, sum3, sum4); fuck(sum1+sum3, sum2, sum4); fuck(sum2+sum4, sum1, sum3); fuck(sum3+sum4, sum1, sum2); } } for(int i = 1; i < n-1; i++){ //平行 ll sum1 = fun(1, i, 1, m); for(int k = i+1; k < n; k++){ ll sum2 = fun(i+1, k, 1, m); ll sum3 = fun(k+1, n, 1, m); fuck(sum1, sum2, sum3); } } for(int i = 1; i < m-1; i++){//平行 ll sum1 = fun(1, n, 1, i); for(int k = i+1; k < m; k++){ ll sum2 = fun(1, n, i+1, k); ll sum3 = fun(1, n, k+1, m); fuck(sum1, sum2, sum3); } } printf("%I64d\n", minn); } return 0; }
- 1
信息
- ID
- 1445
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 9
- 已通过
- 1
- 上传者