HDOJ 1044 Collect More Jewels

来源:互联网 发布:mt4软件官网 编辑:程序博客网 时间:2024/05/05 21:44

         题目比一般的图类的题目稍微绕了点弯子。要根据问题建立解题所需要的图。起始点@和终止点<以及Jewels点共同构成图的点,其之间的最短路径构成了图的边。根据新构成的图,利用深度优先进行解题就可以了。我的解法采用maze存储原问题的图。使用map数组存储最终创建的图,其中记录了临接点和路径长度(map[0].index记录了临接点的个数,其余点的index记录了存储在jewels中Jewel的索引)。建立图的时候,反复进行宽度优先搜索,将临接点存储到map中。然后对map进行深度优先搜索就可以了。

#include<queue>using namespace std;#include<stdio.h>int width,height,jewelsNum;struct Point{    int col,row,value;};struct Map{    int index,step;};Point jewels[12];bool mapVisited[12];Map map[12][12];char maze[51][51];const int choice[4][2]={{1,0},{0,1},{-1,0},{0,-1}};int result,sumValue;char target;inline void init(){    int assist;    sumValue=0;    for(int i=1;i<=jewelsNum;i++)    {        scanf("%d",&jewels[i].value);        sumValue+=jewels[i].value;    }    jewelsNum+=1;    target=jewelsNum+'A';    for(int i=0;i<height;i++)    {        getchar();        for(int j=0;j<width;j++)        {            scanf("%c",&maze[i][j]);            if(maze[i][j]=='@')            {                maze[i][j]='A';                jewels[0].row=i;                jewels[0].col=j;                jewels[0].value=0;            }            else if(maze[i][j]=='<')            {                maze[i][j]=target;                jewels[jewelsNum].row=i;                jewels[jewelsNum].col=j;                jewels[jewelsNum].value=0;            }            else if(maze[i][j]>='A'&&maze[i][j]<='J')            {                maze[i][j]+=1;                assist=maze[i][j]-'A';                jewels[assist].row=i;                jewels[assist].col=j;            }        }    }}inline bool check(int r,int c){    return r<0||r>=height||c<0||c>=width;}inline void buildMap(){    bool visited[51][51];    for(int i=0;i<=jewelsNum;i++)    {        memset(visited,0,sizeof(visited));        map[i][0].index=0;        visited[jewels[i].row][jewels[i].col]=true;        queue<Point> que;        que.push(jewels[i]);        que.front().value=0;        while(!que.empty())        {            Point newPoint;            for(int j=0;j<4;j++)            {                newPoint.row=que.front().row+choice[j][0];                newPoint.col=que.front().col+choice[j][1];                if(check(newPoint.row,newPoint.col)||maze[newPoint.row][newPoint.col]=='*'                    ||visited[newPoint.row][newPoint.col]) continue;                visited[newPoint.row][newPoint.col]=true;                newPoint.value=que.front().value+1;                que.push(newPoint);                if(maze[newPoint.row][newPoint.col]!='.')                {                    map[i][0].index++;                    map[i][map[i][0].index].index=maze[newPoint.row][newPoint.col]-'A';                    map[i][map[i][0].index].step=newPoint.value;                }            }            que.pop();        }    }}void solve(int depth,int limit,int max){    int row,col;    for(int i=1;i<=map[depth][0].index;i++)    {         row=jewels[map[depth][i].index].row;        col=jewels[map[depth][i].index].col;        if(map[depth][i].step>limit||(map[depth][i].step==limit&&maze[row][col]!=target)||mapVisited[map[depth][i].index]||maze[row][col]=='*') continue;        if(result==sumValue) return ;        if(maze[row][col]==target&&max>=result)            result=max;        mapVisited[map[depth][i].index]=true;        solve(map[depth][i].index,limit-map[depth][i].step,max+jewels[map[depth][i].index].value);        mapVisited[map[depth][i].index]=false;    }}int main(){    //freopen("Collect More Jewels.txt","r",stdin);    int caseNum,limit;    scanf("%d",&caseNum);    for(int i=1;i<=caseNum;i++)    {        scanf("%d%d%d%d",&width,&height,&limit,&jewelsNum);        init();        buildMap();        memset(mapVisited,0,sizeof(mapVisited));        result=0;        mapVisited[0]=true;        solve(0,limit,0);        if(result)            printf("Case %d:\nThe best score is %d.\n",i,result);        else            printf("Case %d:\nImpossible\n",i);        if(i!=caseNum)            printf("\n");    }}