11055: 【原1055】二哥切巧克力
题目
题目描述
author: oldherl zyz 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/1055
Description
二哥有一大块矩形平板巧克力,被划分成RxC个小方格。
今天他要从这上面切下一个aichimi形的巧克力送给它的女友。
所谓aichimi形就是一个边长至少为3的正方形切掉四个边长为1的角的形状。下面是一个边长为4的aichimi形:
##
####
####
##
二哥(此时)只有一个女友所以只要切下一块就可以了。
由于这巧克力是某超市的便宜货,每个方格的密度都不同,可能为0.0至0.9g/cm^2不等。
二哥要求这块aichimi形巧克力的重心恰好在中心处,这样他才能给女友表演一个手指转巧克力的“绝活”。
请问符合要求的最大的aichimi形边长是多少呢?
Input Format
第一行为数据组数T
每组数据第一行两个数R和C,表示巧克力板的大小
接下来的R行每行C个数字字符(0到9),表示该方格的密度,单位0.1g/cm2
Output Format
共T行
对于每组数据输出一个整数A表示符合要求的最大aichimi形的边长,如果没有则输出IMPOSSIBLE
Hint
\(3 \leq R \leq 300, 3 \leq C \leq 300\)
第一个样例的答案如下图
.......
..222..
.21152.
.32913.
.24212.
..222..
Sample Input
2
6 7
1111111
1122271
1211521
1329131
1242121
1122211
3 3
123
234
345
Sample Output
5
IMPOSSIBLE
FineArtz's solution
/* 二哥切巧克力 */
#include <iostream>
#include <cmath>
using namespace std;
int main(){
int T;
cin >> T;
while (T--){
int c, r;
char ch;
int a[305][305], sum[305][305];
int sumx[305][305], sumy[305][305];
cin >> r >> c;
for (int i = 0; i <= r; ++i){
sum[i][0] = 0;
sumx[i][0] = 0;
sumy[i][0] = 0;
}
for (int j = 0; j <= c; ++j){
sum[0][j] = 0;
sumx[0][j] = 0;
sumy[0][j] = 0;
}
for (int i = 1; i <= r; ++i){
for (int j = 1; j <= c; ++j){
cin >> ch;
a[i][j] = ch - '0';
sum[i][j] = a[i][j] + sum[i][j - 1] + sum[i - 1][j] - sum[i - 1][j - 1];
}
}
for (int i = 1; i <= r; ++i){
for (int j = 1; j <= c; ++j){
sumx[i][j] = sumx[i - 1][j] + i * (sum[i][j] - sum[i - 1][j]);
sumy[i][j] = sumy[i][j - 1] + j * (sum[i][j] - sum[i][j - 1]);
}
}
bool flag = false;
for (int k = min(r, c); k >= 3; --k){
for (int i = 1; i <= r - k + 1; ++i){
for (int j = 1; j <= c - k + 1; ++j){
int x = i + k - 1, y = j + k - 1;
int s = sum[x][y] - sum[i - 1][y] - sum[x][j - 1] + sum[i - 1][j - 1]
- a[i][j] - a[i][y] - a[x][j] - a[x][y];
double wx = sumx[x][y] - sumx[i - 1][y] - sumx[x][j - 1] + sumx[i - 1][j - 1]
- i * a[i][j] - i * a[i][y] - x * a[x][j] - x * a[x][y];
double wy = sumy[x][y] - sumy[i - 1][y] - sumy[x][j - 1] + sumy[i - 1][j - 1]
- j * a[i][j] - y * a[i][y] - j * a[x][j] - y * a[x][y];
if (s == 0){
flag = true;
cout << k << '\n';
break;
}
wx = wx / s;
wy = wy / s;
if (abs(2 * wx - i - x) < 1e-8 && abs(2 * wy - j - y) < 1e-8){
flag = true;
cout << k << '\n';
break;
}
}
if (flag) break;
}
if (flag) break;
}
if (!flag) cout << "IMPOSSIBLE\n";
}
return 0;
}