现在的位置: 首页 > 综合 > 正文

HDOJ 1044 Collect More Jewels

2013年11月27日 ⁄ 综合 ⁄ 共 2873字 ⁄ 字号 评论关闭

         题目比一般的图类的题目稍微绕了点弯子。要根据问题建立解题所需要的图。起始点@和终止点<以及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");
    }
}

 

抱歉!评论已关闭.