题目链接:https://cn.vjudge.net/problem/UVA-10798
#include<bits/stdc++.h>
#pragma comment(linker,"/STACK:1024000000,1024000000")
using namespace std;
#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
#define read(x,y) scanf("%d%d",&x,&y)
#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define ll long long
const int maxn =25;
const int mod=1e9+7;
ll powmod(ll x,ll y) {ll t;for(t=1;y;y>>=1,x=x*x%mod) if(y&1) t=t*x%mod;return t;}
ll gcd(ll x,ll y) { return y==0?x:gcd(y,x%y); }
///head
/*
题目大意:这道题目意思很关键,
就是说路径必须是要唯一的,
我开始时读的以为是每个方向最小值取最大即可,
其实并不是。。。找一条唯一的路径,使得不论哪个方向踩的花数的最大值最小,
首先肯定用优先队列来看扩展节点,从权重最小的开始能保证找到最优解,
其次就是状态的问题了,由于几何对称性,
可以用状态数组唯一的标识,一条路径在所有方向产生的权重,
(注意,最多也就是边长,数组范围没有越界)。
这样一分析,问题就变成了普通的最短路BFS了。
*/
struct node
{
int x,y;
int l,r,u,d;
int w;
node(int tx=0,int ty=0,int tl=0,int tu=0,int tr=0,int td=0)
{
x=tx,y=ty;
l=tl,r=tr,u=tu,d=td;
w=max(max(l,r),max(u,d));
}
bool operator<(const node & y) const
{
return w>y.w;///最小堆
}
};
int n;
int vis[maxn][maxn][maxn][maxn][maxn][maxn];
int mp[maxn][maxn];
char s[maxn];
int d1[]={0,0,1,-1};
int d2[]={1,-1,0,0};
int bfs(int x)
{
memset(vis,0,sizeof(vis));
priority_queue<node> pq;
pq.push(node(x,x,0,0,0,0));
vis[x][x][0][0][0][0]=1;
while(!pq.empty())
{
node tp=pq.top();pq.pop();
for(int i=0;i<4;i++)
{
node s=tp;
int tx=s.x+d1[i];
int ty=s.y+d2[i];
if(tx<=0||tx>n||ty<=0||ty>n) return tp.w;
s.x=tx;
s.y=ty;
if(mp[tx][ty]) s.l++;
if(mp[ty][n-tx+1]) s.u++;
if(mp[n-tx+1][n-ty+1]) s.r++;
if(mp[n-ty+1][tx]) s.d++;
if(vis[tx][ty][s.l][s.u][s.r][s.d]) continue;
vis[tx][ty][s.l][s.u][s.r][s.d]=1;
pq.push(node(s.x,s.y,s.l,s.u,s.r,s.d));
}
}
return -1;
}
int main()
{
while(scanf("%d",&n)&&n)
{
for(int i=1;i<=n;i++)
{
scanf("%s",s+1);
for(int j=1;j<=n;j++)
if(s[j]=='R') mp[i][j]=1;
else mp[i][j]=0;
}
printf("At most %d rose(s) trampled.\n", bfs(n/2+1));
}
return 0;
}