1057: Beautiful Garden
Time Limit: 5 Sec
Memory Limit: 128 MB
Submit: 25
Solved: 12
[ Submit][ Status][ Web Board]
Description
There's a beautiful garden whose size is n × m in Edward's house. The garden can be
partitioned into n × m equal-sized square chunks. There are some kinds of flowers
planted in each square chunk which can be represented by using lowercase letters.
However, Edward thinks the garden is not beautiful enough. Edward wants to build a
water pool in the garden. So that the garden would look like symmetric (both
horizontally and vertically). The water pool is a rectangle whose size is p × q and the
center of the water pool is also the center of the garden.
Something else important you should know is:
n, m, p and q are all even.
p is always less than n.
q is always less than m.
The borders of the water pool are parallel to the border of garden.
Edward wants to know how many different pairs of (p, q) he can choose.
Input
There are multiple test cases. The first line of input contains an integer T indicating
the number of test cases. For each test case:
The first line contains two integers n and m (1 <= n, m <= 2000, n and m are even),
indicating the size of the garden. For next n lines, each line contains m characters
showing the garden.
It is guaranteed that only lowercase letters will appear.
Output
For each test case, output an integer indicating the number of choices to build the
water pool.
Sample Input
3
6 8
acbbbbca
dcaccacd
cdaddadc
cdaddadc
dcaccacd
acbbbbca
6 8
acbcbbca
dcaccacd
cdaddadc
cdaddadc
dcaccacd
acbbbbca
6 8
acbbbbca
dcadcacd
cdaddadc
cdaddadc
dcaccacd
acbbbbca
Sample Output
6
0
3
HINT
For the first sample, you have following six choices (blank rectangle means the water
pool):
很蛋疼的一道题,需要仔细调试。还有具体怎么计算呢?若下标均从0开始,显然上面的可抹除部分有2行(1与2),3列(1,2,3),那么答案就是2*3,其他情况均用这种办法求解。
代码:
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<string>
#include<deque>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
char pos[2009][2009];
int hang,lie;
inline bool huiwen(const char s[])
{
int len=strlen(s);
int i;
for (i=0; i<len/2;i++)
{
if(s[i]!=s[len-1-i])
return false;
}
return true;
}
int main(void)
{
int t,i,j,l,r;
scanf("%d",&t);
while (t--)
{
memset(pos,0,sizeof(pos));
scanf("%d%d",&hang,&lie);
for (i=0; i<hang; i++)
{
scanf("%s",pos[i]);
}
l=hang/2-1;
r=lie/2-1;
for (i=0; i<hang/2; i++)//判断上下是否相同且回文
{
if( (strcmp(pos[i],pos[hang-1-i])!=0) || (!huiwen(pos[i])) || (!huiwen(pos[hang])))
{
l=i;
break;
}
}
bool ok=0;
for (i=0; i<lie/2; i++)//列相同判断
{
for (j=l; j<=hang-1-l; j++)
{
if(pos[j][i]!=pos[j][lie-1-i])
{
r=i;
ok=1;
break;
}
}
if(ok)
break;
}
for (i=0; i<r; i++)//列回文判断(放到上面的for里十分麻烦,独立出来判断)
{
for (j=l; j<hang/2; j++)
{
if(pos[j][i]!=pos[hang-1-j][i])
{
r=min(r,i);//肯定要取小的那列
ok=1;
break;
}
}
if(ok)
break;
}
printf("%d\n",l*r);//输出答案
}
return 0;
}