[Elite 2008 Dec USACO]Jigsaw Puzzles

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define Up num[0]
#define Right num[1]
#define Down num[2]
#define Left num[3]

char ca,cb,cc,cd;
int r,c,rc;
bool v[110];

class Jigsaw
{
public:
    int serialNumber;
    char num[4];
public:
    void readIn()
    {
        scanf("%d%*c%c%*c%c%*c%c%*c%c%*c",&serialNumber,num,num+1,num+2,num+3);
    }
    void printOut()
    {
        printf("%d %c %c %c %c\n",serialNumber,num[0],num[1],num[2],num[3]);
    }
    int checkCorner()
    {
        int i;
        for (i=0; i<4; i++)
        {
            if (num[i] == '0' && num[(i+1)%4] == '0')
                return i;
        }
        return -1;
    }
    int checkSuit2c()
    {
        int i;
        for (i=0; i<4; i++)
        {
            if (num[i] == ca && num[(i+1)%4] == cb)
                return i;
        }
        return -1;
    }
    int checkSuit3c()
    {
        int i;
        for (i=0; i<4; i++)
        {
            if (num[i] == ca && num[(i+1)%4] == cb && num[(i+2)%4] == cc)
                return i;
        }
        return -1;
    }
    int checkSuit4c()
    {
        int i;
        for (i=0; i<4; i++)
        {
            if (num[i] == ca && num[(i+1)%4] == cb && num[(i+3)%4] == cc)
                return i;
        }
        return -1;
    }
};
Jigsaw js[110];
Jigsaw tb[11][11];
bool check_and_rotate(int x,int y,int d)
{
    int t;
    if (x == 0 && y == 0)
    {
        t=js[d].checkCorner();
        if (t == -1)
            return false;
        tb[x][y].serialNumber=js[d].serialNumber;
        tb[x][y].Left=js[d].num[t];
        tb[x][y].Up=js[d].num[(t+1)%4];
        tb[x][y].Right=js[d].num[(t+2)%4];
        tb[x][y].Down=js[d].num[(t+3)%4];
        return true;
    }
    if (x == 0)
        cb='0';
    else
        cb=tb[x-1][y].Down;
    if (y == 0)
        ca='0';
    else
        ca=tb[x][y-1].Right;
    if (y == c-1)
    {
        cc='0';
        t=js[d].checkSuit3c();
        if (t == -1)
            return false;
        tb[x][y].serialNumber=js[d].serialNumber;
        tb[x][y].Left=js[d].num[t];
        tb[x][y].Up=js[d].num[(t+1)%4];
        tb[x][y].Right=js[d].num[(t+2)%4];
        tb[x][y].Down=js[d].num[(t+3)%4];
        return true;
    }
    else if (x == r-1)
    {
        cc='0';
        t=js[d].checkSuit4c();
        if (t == -1)
            return false;
        tb[x][y].serialNumber=js[d].serialNumber;
        tb[x][y].Left=js[d].num[t];
        tb[x][y].Up=js[d].num[(t+1)%4];
        tb[x][y].Right=js[d].num[(t+2)%4];
        tb[x][y].Down=js[d].num[(t+3)%4];
        return true;
    }
    else
    {
        t=js[d].checkSuit2c();
        if (t == -1)
            return false;
        tb[x][y].serialNumber=js[d].serialNumber;
        tb[x][y].Left=js[d].num[t];
        tb[x][y].Up=js[d].num[(t+1)%4];
        tb[x][y].Right=js[d].num[(t+2)%4];
        tb[x][y].Down=js[d].num[(t+3)%4];
        return true;
    }
    return false;
}
bool DFS(int x,int y)
{
    int i,j;
    if (y == c)
    {
        x++;
        y=0;
        if (x == r)
        {
            for (i=0; i<r; i++)
            {
                for (j=0; j<c; j++)
                {
                    tb[i][j].printOut();
                }
            }
            return true;
        }
        return DFS(x,y);
    }
    for (i=0; i<rc; i++)
    {
        if (v[i] == true)
            continue;
        if (check_and_rotate(x,y,i) == true)
        {
            v[i]=true;
            if (DFS(x,y+1) == true)
                return true;
            v[i]=false;
        }
    }
    return false;
}
int main()
{
    int i,j;
    scanf("%d%d",&r,&c);
    rc=r*c;
    for (i=0; i<rc; i++)
    {
        js[i].readIn();
        v[i]=false;
    }
    DFS(0,0);
    return 0;
}

USACO Elite 2008 December Competition Silverios

題意:給你一些正方形的拼圖碎塊,每一個碎塊有四個邊,每邊都有一個記號,分別是小寫字母a-z。其中沒有標記的邊,也就是邊界的邊用'0'標記。題目給定一個矩陣,把這些碎塊放進去,要求每一個邊相接的記號必須同樣,邊界上的邊必須是'0'。ui

解法:DFS。這個操做起來仍是挺麻煩的,作處理的時候要當心一些。spa

相關文章
相關標籤/搜索