题意:给定一个长方形网格,要把它切成完全相同4个部分(这里完全相同指可以旋转平移后能重叠)。把4个重叠后每个网格对应有四个数字相加,得到一种方案,所有格子中和最小就是该种方案的值,在多种方案中,最后问最大的解能使多少。
思路:首先任意一种划分可以映射到4个相同的长方形, 也就是说一种不是长方形的方案 可以转化为一种长方形的。那么我们就只需要找4个完全相同的长方形就可以。一共有以下画法:
下面画图时基于n>m。边长要满足一定条件要自己注意。
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define debug(x) printf(#x"= %d\n",x);
using namespace std;
struct node {
int a[][];
int n, m;
void rota() {//旋转90度
int b[][];
for (int i = ; i < n; ++i) {
for (int j = ; j < m; ++j) {
b[j][n - i - ] = a[i][j];
}
}
swap(n, m);
for (int i = ; i < n; ++i)
for (int j = ; j < m; ++j)
a[i][j] = b[i][j];
}
} p[], s;
int a[][];
int n, m;
int ans;
node cur[];
void gao(int now) {
if (now == ) {
for (int i = ; i < ; ++i)
if (cur[i].n != cur[i + ].n || cur[i].m != cur[i + ].m)
return; int minn = ;
for (int i = ; i < cur[].n; ++i) {
for (int j = ; j < cur[].m; ++j) {
int sum = ;
for (int k = ; k < ; ++k) {
sum += cur[k].a[i][j];
}
// printf("%d %d %d\n",i,j,sum);
if (sum < minn)
minn = sum;
}
}
if (minn > ans)
ans = minn; return;
}
cur[now] = p[now];
gao(now + );
for (int i = ; i < ; ++i) {
cur[now].rota();
gao(now + );
}
}
int main() {
while (scanf("%d%d", &n, &m) != EOF) {
for (int i = ; i < n; ++i)
for (int j = ; j < m; ++j)
scanf("%d", &a[i][j]);
//debug(m);
ans = ;
if (n % == ) {
for (int i = ; i < ; ++i) {
for (int j = n / * i; j < n / * (i + ); ++j) {
for (int k = ; k < m; ++k) {
p[i].a[j % (n / )][k] = a[j][k];
}
}
p[i].n = n / ;
p[i].m = m;
}
gao();
} if (m % == ) {
for (int i = ; i < ; ++i) {
for (int j = ; j < n; ++j) {
for (int k = i * (m / ); k < (i + ) * m / ; ++k) {
p[i].a[j][k % (m / )] = a[j][k];
}
}
p[i].n = n;
p[i].m = m / ;
}
gao();
} if (n % == && m % == ) {
for (int i = ; i < ; ++i) {
for (int j = (i / ) * n / ; j < (i / + ) * n / ; ++j) {
for (int k = (i % ) * m / ; k < (i % + ) * m / ;
++k) {
p[i].a[j % (n / )][k % (m / )] = a[j][k];
}
}
p[i].n = n / ;
p[i].m = m / ;
}
gao();
} s.n = n;
s.m = m;
for (int i = ; i < n; ++i)
for (int j = ; j < m; ++j)
s.a[i][j] = a[i][j];
if (n < m) {
s.rota();
swap(n, m);
}
if ( * s.n == * s.m && s.m % == && s.n % == ) {
for (int i = ; i < ; ++i) {
for (int j = ; j < m; ++j) {
for (int k = i * m / ; k < (i + ) * m / ; ++k) {
p[i].a[j][k % (m / )] = s.a[j][k];
}
}
p[i].n = m;
p[i].m = m / ;
}
for (int i = m; i < n; ++i)
for (int j = ; j < m; ++j)
p[].a[i - m][j] = s.a[i][j];
p[].n = n - m;
p[].m = m;
gao(); for (int i = ; i < ; ++i) {
for (int j = n - m; j < n; ++j) {
for (int k = i * m / ; k < (i + ) * m / ; ++k) {
p[i].a[j - (n - m)][k % (m / )] = s.a[j][k];
}
}
p[i].n = m;
p[i].m = m / ;
}
for (int i = ; i < n - m; ++i)
for (int j = ; j < m; ++j)
p[].a[i][j] = s.a[i][j];
p[].n = n - m;
p[].m = m;
gao();
} if (s.n == * s.m && s.m % == ) {
for (int i = ; i < n / ; ++i)
for (int j = ; j < m / ; ++j)
p[].a[i][j] = s.a[i][j];
p[].n = s.n / ;
p[].m = s.m / ;
for (int i = ; i < n / ; ++i)
for (int j = m / ; j < m; ++j)
p[].a[i][j - m / ] = s.a[i][j];
p[].n = s.n / ;
p[].m = s.m / ;
for (int i = n / ; i < n / * ; ++i)
for (int j = ; j < m; ++j)
p[].a[i - n / ][j] = s.a[i][j];
p[].n = s.n / ;
p[].m = s.m;
for (int i = n / * ; i < n; ++i)
for (int j = ; j < m; ++j)
p[].a[i - n / * ][j] = s.a[i][j];
p[].n = n / ;
p[].m = m;
gao(); for (int i = n / ; i < n / * ; ++i)
for (int j = ; j < m / ; ++j)
p[].a[i - n / ][j] = s.a[i][j];
p[].n = s.n / ;
p[].m = s.m / ;
for (int i = n / ; i < n / * ; ++i)
for (int j = m / ; j < m; ++j)
p[].a[i - n / ][j - m / ] = s.a[i][j];
p[].n = s.n / ;
p[].m = s.m / ;
for (int i = ; i < n / ; ++i)
for (int j = ; j < m; ++j)
p[].a[i][j] = s.a[i][j];
p[].n = s.n / ;
p[].m = s.m;
for (int i = n / * ; i < n; ++i)
for (int j = ; j < m; ++j)
p[].a[i - n / * ][j] = s.a[i][j];
p[].n = n / ;
p[].m = m;
gao(); for (int i = n / ; i < n; ++i)
for (int j = ; j < m / ; ++j)
p[].a[i - n / ][j] = s.a[i][j];
p[].n = s.n / ;
p[].m = s.m / ;
for (int i = n / ; i < n; ++i)
for (int j = m / ; j < m; ++j)
p[].a[i - n / ][j - m / ] = s.a[i][j];
p[].n = s.n / ;
p[].m = s.m / ;
for (int i = ; i < n / ; ++i)
for (int j = ; j < m; ++j)
p[].a[i][j] = s.a[i][j];
p[].n = s.n / ;
p[].m = s.m;
for (int i = n / ; i < n / ; ++i)
for (int j = ; j < m; ++j)
p[].a[i - n / ][j] = s.a[i][j];
p[].n = n / ;
p[].m = m;
gao(); }
printf("%d\n", ans); }
return ;
}