第六届湖南省省赛 Biggest Number(DFS+BFS,巧妙剪枝)

来源:互联网 发布:mac快捷键删除 编辑:程序博客网 时间:2024/05/20 01:10

Biggest NumberTime Limit: 2000ms, Special Time Limit:5000ms, Memory Limit:65536KBTotal submit users: 31, Accepted users: 15Problem 10935 : No special judgementProblem description  You have a maze with obstacles and non-zero digits in it:

 

 

You can start from any square, walk in the maze, and finally stop at some square. Each step, you may only walk into one of the four neighbouring squares (up, down, left, right) and you cannot walk into obstacles or walk into a square more than once. When you finish, you can get a number by writing down the digits you encounter in the same order as you meet them. For example, you can get numbers 9784, 4832145 etc. The biggest number you can get is 791452384, shown in the picture above.

 

Your task is to find the biggest number you can get.

Input  There will be at most 25 test cases. Each test begins with two integers R and C (2<=R,C<=15, R*C<=30), the number of rows and columns of the maze. The next R rows represent the maze. Each line contains exactly C characters (without leading or trailing spaces), each of them will be either '#' or one of the nine non-zero digits. There will be at least one non-obstacle squares (i.e. squares with a non-zero digit in it) in the maze. The input is terminated by a test case with R=C=0, you should not process it.
Output  For each test case, print the biggest number you can find, on a single line.
Sample Input
3 7##9784###123####45###0 0
Sample Output
791452384
题意:从任意一个非#格子出发,可以往上下左右走,一个格子只能走一次,求字典序最大的路径(先保证长度最大,再保证字典序)

思路:容易想到直接DFS爆搜,可是那样当然会TLE

那么怎么办呢?我们就需要用BFS去判断当前这个点所能走到的其他所有点的个数,如果当前已经走过的点的个数+理想状况下可以走到的点的个数<已经得到的最优解的话就不用往下搜了。

具体可以看代码

代码:

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <vector>#include <string>#include <queue>using namespace std;const int N = 35;int n,m,len;char ma[N][N];bool flag[N][N];bool vis[N][N];int dir[][2] = {{1,0},{-1,0},{0,-1},{0,1}};struct Node{    int x,y;};char last[N],ans[N],ans1[N];bool check(int x,int y){    if(x<1||x>n||y<1||y>m||ma[x][y]=='#') return false;    return true;}Node que[400];int bfs(int r,int c){    int num=0;    memset(flag,0,sizeof(flag));    Node a,next;    a.x=r,a.y=c;    int head=0,tail=0;    que[tail++]=a;    flag[a.x][a.y]=1;    while(head!=tail)    {        Node now=que[head++];        for(int i=0; i<4; i++)        {            next.x=now.x+dir[i][0];            next.y=now.y+dir[i][1];            if(!check(next.x,next.y)||flag[next.x][next.y]||vis[next.x][next.y]) continue;            flag[next.x][next.y]=1;            num++;            que[tail++]=next;        }    }    return num;}void dfs(int x,int y,int step){    if(step>len||(step==len&&strcmp(ans,last)>0))    {        len=step;        strcpy(last,ans);    }    int num=bfs(x,y);    strcpy(ans1,ans);    ans1[step]='9';    if(step+num<len||(step+num==len&&strcmp(ans1,last)<0)) return;    for(int i=0; i<4; i++)    {        int r=x+dir[i][0],c=y+dir[i][1];        if(!check(r,c)||vis[r][c]) continue;        vis[r][c]=1;        ans[step]=ma[r][c];        dfs(r,c,step+1);        vis[r][c]=0;    }}int main(){    //  freopen("f.in","r",stdin);    //  freopen("f.txt","w",stdout);    while(~scanf("%d %d",&n,&m)&&(n+m))    {        int cnt=0;        for(int i=1; i<=n; i++)            scanf("%s",ma[i]+1);        for(int i=1; i<=n; i++)            for(int j=1; j<=m; j++)                if(ma[i][j]!='#')                    cnt++;        len=-1;        memset(last,0,sizeof(last));        memset(ans,0,sizeof(ans));        for(int i=1; i<=n; i++)            for(int j=1; j<=m; j++)            {                if(ma[i][j]=='#'||(len==cnt&&ma[i][j]<last[0])) continue;                memset(vis,0,sizeof(vis));                vis[i][j]=1;                ans[0]=ma[i][j];                dfs(i,j,1);            }        printf("%s\n",last);    }    return 0;}




0 0
原创粉丝点击