UVA11882
这道题还是比较简单的,但是时间确实有点短
所以剪枝还是非常重要的,之前交过的代码都超时了,果然我还是个渣渣;
这里用到了一个非常简单的结构体node
函数ll有点像bfs
主要问题还是剪枝
如果已经走的长度加上还能走的最大长度小于ans(当前最优解)的长度,直接return;
如果以上两者长度相等,但是最优解的字典序大,return;
然后再比较当前最优解和目前的string s(update函数)。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
int r,c;
int v[30][30],vv[30][30];
char g[30][30];
int dr[]={1,-1,0,0};
int dc[]={0,0,-1,1};
string ans,s;
struct node
{
int x,y;
};
node q[1000];
void update(string s)
{
int l1=s.size();
int l2=ans.size();
if(l1>l2||(l1==l2&&s>ans))
{
ans=s;
}
}
int ll(int a,int b)
{
int head=0,tail=0;
int cnt=0;
q[tail].x=a;
q[tail++].y=b;
memcpy(vv,v,sizeof(v));
while(head!=tail)
{
for(int i=0;i<4;i++)
{
int xx=q[head].x+dr[i];
int yy=q[head].y+dc[i];
if(xx>=0&&xx<r&&yy>=0&&yy<c&&vv[xx][yy]==0&&g[xx][yy]!='#')
{
vv[xx][yy]=1;
q[tail].x=xx;
q[tail++].y=yy;
cnt++;
}
}
head++;
}
return cnt;
}
void dfs(int a,int b,string s,int d)
{
int l=ll(a,b);
if(d+l<ans.size())
return;
if(d+l==ans.size()&&(s+'z')<ans)//注意s要加上'z'
return;
update(s);
for(int i=0;i<4;i++)
{
int xx=a+dr[i];
int yy=b+dc[i];
if(xx>=0&&yy>=0&&xx<r&&yy<c&&v[xx][yy]==0&&g[xx][yy]!='#')
{
v[xx][yy]=1;
dfs(xx,yy,s+g[xx][yy],d+1);
v[xx][yy]=0;
}
}
}
int main()
{
while(cin>>r>>c&&r)
{
ans="";
getchar();
for(int i=0;i<r;i++)
scanf("%s",g[i]);
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++)
{
if(g[i][j]!='#')
{
memset(v,0,sizeof(v));
v[i][j]=1;
s="";
s=s+g[i][j];
dfs(i,j,s,1);
}
}
}
cout<<ans<<endl;
}
return 0;
}
1831




被折叠的 条评论
为什么被折叠?



