pku 1069 百慕大三角

//g++ re c++ ac memset TLE

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
using namespace std;

const int MAX_SIZE = 25;

class Bermuda
{
public:
    void input();
    bool order();
private:
    int bermudasize;
    vector <int> triangle;
    bool hash[2 * MAX_SIZE][4 * MAX_SIZE]; //坐标化 y为偶数向上 奇数为向下
    bool dfs(int, int);
    void change(int, int, int, bool);
    bool avail(int, int, int);
    int availmax(int, int);
};

void Bermuda::input()
{
    int n, i;
    triangle.clear();
    scanf("%d %d", &bermudasize, &n);
    for (i = 0; i < n; ++i)
    {
        int trisize;
        scanf("%d", &trisize);
        if (trisize <= bermudasize)
        {
            triangle.push_back(trisize);
        }
    }
    sort(triangle.begin(), triangle.end());
    vector <int> ::iterator it, next;
    for (it = triangle.begin(); it != triangle.end(); ++it)
    {
        for (next = triangle.begin(); next != it; ++next)
        {
            if (*it % *next == 0)
            {
                triangle.erase(it);
                it--;
                break;
            }
        }
    }
}

bool Bermuda::order()
{
    int i, row, col;
    for (i = 0; i < triangle.size(); ++i)
    {
        if (bermudasize % triangle[i] == 0)
        {
            return true;
        }
    }
    //memset(hash, 0, sizeof(hash)); // Time Limit Exceeded
    for (row = 0; row < 2 * bermudasize; ++row)
    {
        for (col = 0; col < 4 * bermudasize; ++col)
        {
            hash[row][col] = false;
        }
    }
    for (row = 0; row < bermudasize; ++row)
    {
        for (col = 0; col <= 2 * (bermudasize - row - 1); ++col)
        {
            hash[row][col] = true;
        }
    }
    for (row = bermudasize; row < 2 * bermudasize; ++row)
    {
        for (col = 4 * bermudasize - 2 * (row - bermudasize) - 1; col <= 4 * bermudasize - 1; ++col)
        {
            hash[row][col] = true;
        }
    }
    return dfs(0, 0);
}

bool Bermuda::dfs(int row, int col)
{
    int i;
    if (row >= 2 * bermudasize)
    {
        return true;
    }
    if (col >= 4 * bermudasize)
    {
        return dfs(row + 1, 0);
    }
    if (hash[row][col])
    {
        return dfs(row, col + 1);
    }
    int sizemax = availmax(row, col);
    for (i = 0; i < triangle.size() && triangle[i] <= sizemax; ++i)
    {
        change(row, col, triangle[i], true);
        if (dfs(row, col + 1))
        {
            return true;
        }
        change(row, col, triangle[i], false);
    }
    return false;
}

int Bermuda::availmax(int row, int col)
{
    int maxsize;
    for (maxsize = 1; maxsize < bermudasize; ++maxsize)
    {
        if (!avail(row, col, maxsize))
        {
            return maxsize - 1;
        }
    }
    return bermudasize;
}

bool Bermuda::avail(int row, int col, int size)
{
    int ablerow, ablecol;
    if (col % 2)
    {
        for (ablerow = row; ablerow < row + size; ++ablerow)
        {
            for (ablecol = col - 2 * (ablerow - row); ablecol <= col; ++ablecol)
            {
                if (ablerow >= 2 * bermudasize || ablecol >= 4 * bermudasize || hash[ablerow][ablecol])
                {
                    return false;
                }
            }
        }
    }
    else
    {
        for (ablerow = row; ablerow < row + size; ++ablerow)
        {
            for (ablecol = col; ablecol <= col + 2 * (row + size - ablerow - 1); ++ablecol)
            {
                if (ablerow >= 2 * bermudasize || ablecol >= 4 * bermudasize || hash[ablerow][ablecol])
                {
                    return false;
                }
            }
        }
    }
    return true;
}

void Bermuda::change(int row, int col, int size, bool flag)
{
    int ablerow, ablecol;
    if (col % 2)
    {
        for (ablerow = row; ablerow < row + size; ++ablerow)
        {
            for (ablecol = col - 2 * (ablerow - row); ablecol <= col; ++ablecol)
            {
                hash[ablerow][ablecol] = flag;
            }
        }
    }
    else
    {
        for (ablerow = row; ablerow < row + size; ++ablerow)
        {
            for (ablecol = col; ablecol <= col + 2 * (row + size - ablerow - 1); ++ablecol)
            {
                hash[ablerow][ablecol] = flag;
            }
        }
    }
}

int main()
{
    int T;
    Bermuda test;
    scanf("%d", &T);
    while (T--)
    {
        test.input();
        printf("%s"n", test.order() ? "YES" : "NO");
    }
    return 0;
}

posted on 2009-05-10 16:46  ZAFU_VA  阅读(339)  评论(0)    收藏  举报

导航