//目录

广搜,智能拼图(ZOJ1079)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=79

解题报告:

思路简单,写法太难。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

///x,y的增量
int dx[4] = {1,0,-1,0};
int dy[4] = {0,1,0,-1};
int queue[501];
int used[500];


///使用数组piece表示拼图的每一片的信息
struct {
    int id;        ///这一片,他的相邻的片的编号
    int side;    ///这一片,他的相邻片的邻边的编号
}piece[500][4];

///使用数组pos保存拼图的位置信息,输出结果
struct position{
    int x, y;    ///坐标
    int id;        ///卡片的编号
    int side;    ///下底的编号
}pos[500];


int compare(const void *a,const void *b)
{
    int c;
    if((c=(((struct position*)a)->x-((struct position*)b)->x))!=0)
        return(c);
    return((((struct position*)a)->y-((struct position*)b)->y));
}

int main()
{
    int n, k;    ///卡片的数量和k个卡片的信息量
    int i;
    int cases = 1;

    while(scanf("%d", &n) && n)
    {
        scanf("%d", &k);
        memset(piece, 255, sizeof(piece));
        memset(used, 0, sizeof(used));
        int a, b, c, d;
        for(i=0; i<k; i++)
        {
            scanf("%d%d%d%d", &a, &b, &c, &d);
            piece[a][b].id = c;
            piece[a][b].side = d;
            piece[c][d].id = a;
            piece[c][d].side = b;
        }

        ///编号初始化
        for(i=0; i<n; i++)
            pos[i].id = i;


        pos[0].x = 0;
        pos[0].y = 0;
        pos[0].side = 0;
        used[0] = 1;
        queue[0] = 0;

        int first = 0;    ///队列的头部位置
        int count = 0;    ///队列的尾部位置

        ///队列还没有搜索完毕
        while (first<=count)
        {
            ///搜索当前节点
            a = queue[first];    ///编号
            int x0 = pos[a].x;
            int y0 = pos[a].y;
            d = pos[a].side;
            int number;            ///相邻卡片的编号

            ///对相邻卡片的4边搜索
            for(i=0; i<4; i++)
            {
                ///输入数据有卡片的信息
                if((number=piece[a][i].id)>=0)
                    ///该卡片还没有搜过
                    if(used[number]==0)
                    {
                        b = piece[a][i].side;
                        used[number] = 1;

                        ///计算相邻卡片的位置和底边的信息

                        ///x&3相当于(x+4)%4
                        pos[number].x = x0+dx[(i-d)&3];
                        pos[number].y = y0+dy[(i-d)&3];
                        pos[number].side = ((b-i+d+2)&3);

                        ///该卡片进入队列
                        queue[++count] = number;
                    }
            }
            first++;    ///搜索下一个节点
        }
        qsort(pos, n, sizeof(position), compare);
        a = pos[0].x;
        b = pos[0].y;
        printf("Instance %d:\n",cases++);
        for(i=0; i<n; i++)
            printf("%5d%5d%6d%2d\n", pos[i].x-a, pos[i].y-b, pos[i].id, pos[i].side);
    }
    return 0;
}

 

posted @ 2016-03-29 23:40  小草的大树梦  阅读(372)  评论(0编辑  收藏  举报