题目大意:
今天你过生日,你爸妈给你买了个chocolate蛋糕,但你爸妈和妹妹很自私,都希望自己分到chocolate最多的的一块蛋糕(侧面告诉你,你只能吃到小于等于他们的chocolate)。让你算出你如何吃到最多的chocolate蛋糕,和求chocolate蛋糕的分割线。
输入
输入第一行是一个整数N,表示蛋糕的边长。接下来N行,每行N个字符(“#”或”.”)描述蛋糕的情况。
输出
输出第一行输出一个整数M表示你最大可以获得巧克力的个数。接下来输出两个整数R和C,描述切割方法,R表示水平切线是介于第R行和R+1行之间,C表示垂直切线介于第C列和第C+1列之间。如果有多种切法,输出任意一种即可。
样例输入
8
…#…#…
.##…#…
…#.
.##…
…#.#…
…#.
…
…#…#…
样例输出
3
3 4
思路:
暴力枚举+求前缀和(方便更新)。
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#define rr register
using namespace std;
int n,b[5000],f[5000][5000];
int maxx,x,y;
char c;
int main()
{
scanf("%d",&n);//输入。
for (rr int i = 1; i <= n; ++i)
{
scanf("\n");//输入换行,也可以用getchar。
for (rr int j = 1; j <= n; ++j)
{
rr int k = 0; scanf("%c",&c);
if (c == '#') k = 1;//标记有巧克力
b[j] = b[j] + k;
f[i][j] = f[i][j-1] + b[j]; //求前缀和。
}
}
for (rr int i = 1; i <= n; ++i)
for (rr int j = 1; j <= n; ++j)
{
rr int t1=f[i][j]; //第1块
rr int t2=f[i][n]-t1;//第2块
rr int t3=f[n][j]-t1;//第3块
rr int t4=f[n][n]-t1-t2-t3; //第4块
if (min(min(t1,t2),min(t3,t4))>maxx)
{
maxx=min(min(t1,t2),min(t3,t4));
x=i;y=j; //更新。
}
}
printf("%d\n%d %d",maxx,x,y);//输出,注意输出格式。
}