uva-519-拼图

给你N*M个碎片,问能否用他们拼成一个矩形,矩形的边缘要全是F,除外界边缘的边要么是I,要么O,不能是F
1.碎片会重复出现,所以同样的碎片在同一个位置,如果已经不能放,直接跳过就行
2.矩形的边缘要全是F,除外界边缘的边要么是I,要么O,所以有I的数量等于0数量,上外边界F数量等于M,其他三边同理

 WA了N遍

#include <stdio.h>
#include<iostream>
#include <string.h>
#include<memory.h>
using namespace std;
int N;
int M;
int flag;
int num[50];
char noPeat[50][4];
int nl = 0;
char m[10][10][4];
int read()
{
    char str[5]={0};
    int IN[4] = { 0 };
    int ON[4] = { 0 };
    int FN[4] = { 0 };
    gets(str);
    for(int i = 0; i < N * M; i++)
    {
        gets(str);
        int ok = 1;
        for(int j = 0; j < nl; j++)
            if(noPeat[j][0] == str[0] && noPeat[j][1] == str[1]
                    && noPeat[j][2] == str[2] && noPeat[j][3] == str[3])
            {
                ok = 0;
                num[j]++;
                break;
            }
        if(ok)
        {
            noPeat[nl][0] = str[0];
            noPeat[nl][1] = str[1];
            noPeat[nl][2] = str[2];
            noPeat[nl][3] = str[3];
            num[nl]++;
            nl++;
        }
        for(int j = 0; j < 4; j++)
        {
            if(str[j] == 'I')
                IN[j]++;
            if(str[j] == 'O')
                ON[j]++;
            if(str[j] == 'F')
                FN[j]++;
        }
    }
    if(FN[0] != M || FN[2] != M)
        return 0;
    if(FN[1] != N || FN[3] != N)
        return 0;
    if(IN[0] != ON[2] || IN[2] != ON[0])
        return 0;
    if(IN[3] != ON[1] || IN[1] != ON[3])
        return 0;
    return 1;
}
int check(int r, int c, char str[4])
{
    if(r == 1 && str[0] != 'F')
        return 0;
    if(r == N && str[2] != 'F')
        return 0;
    if(c == 1 && str[3] != 'F')
        return 0;
    if(c == M && str[1] != 'F')
        return 0;
    if(r != 1 && str[0] == 'F')
        return 0;
    if(r != N && str[2] == 'F')
        return 0;
    if(c != 1 && str[3] == 'F')
        return 0;
    if(c != M && str[1] == 'F')
        return 0;
    if(m[r][c - 1][1] == 'I' && str[3] != 'O')
        return 0;
    if(m[r][c - 1][1] == 'O' && str[3] != 'I')
        return 0;
    if(m[r - 1][c][2] == 'I' && str[0] != 'O')
        return 0;
    if(m[r - 1][c][2] == 'O' && str[0] != 'I')
        return 0;
    return 1;
}
void dfs(int r, int c)
{
    if(c == M + 1)
        dfs(r + 1, 1);
    if(flag)
        return;
    if(r == N + 1)
    {
        flag = 1;
        return;
    }
    for(int i = 0; i < nl; i++)
    {
        if(num[i] && check(r, c, noPeat[i]))
        {
            num[i]--;
            m[r][c][0] = noPeat[i][0];
            m[r][c][1] = noPeat[i][1];
            m[r][c][2] = noPeat[i][2];
            m[r][c][3] = noPeat[i][3];
            dfs(r, c + 1);
            if(flag)
                return;
            m[r][c][0] = 0;
            m[r][c][1] = 0;
            m[r][c][2] = 0;
            m[r][c][3] = 0;
            num[i]++;
        }

    }

}
int main()
{
    freopen("d://1.txt", "r", stdin);
    while (cin >> N >> M && (N + M))
    {
        flag = 0;
        nl = 0;
        memset(num, 0, sizeof(num));
        memset(m, 0, sizeof(m));
        memset(noPeat, 0, sizeof(noPeat));
        int ok = read();
        if(!ok)
        {
            cout << "NO" << endl;
            continue;
        }
        dfs(1, 1);
        if(flag)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/8887437.html