Square Destroyer UVA - 1603

题目传送门

题意:给你一个n*n的用火柴棍拼成的正方形,然后在这个正方一开始先取走m个火柴棍,问你剩下的最少取走多少个可以使这个这些火柴无法构成正方形。

思路:这个题知道是IDA*搜索,可是这个题最大的问题就是把所有的正方形都找出来,现在代码能力太弱了,这个东西写了两个小时都没写出来,最后借鉴了别人的把这个写了出来,剩下的就是枚举删除剩下的正方形每一个边,然后迭代加深搜索还有估值函数,我看了一下最初的图,发现一个边最多能破坏n + 1个正方形,以此作为估值函数,然后抱着试试看的想法交了一下,竟然过了。
PS:代码能力还是有待加强,这个题还可以用DLX,以后学习一下再做一下这个题。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define MAXN 100
#define INF 10000000
#define MOD 1000000007
#define LL long long
#define pi acos(-1.0)

using namespace std;

int n, m;
int ans;
bool link[MAXN];
int is_square[MAXN];
vector<int> square[MAXN];
vector<int> stick[MAXN];
int totsquare;
int totstick;

int h() {
    int cnt = 0;
    for (int i = 1; i <= totsquare; ++i) {
        if (is_square[i] == 0)
            cnt++;
    }
    return cnt;
}

bool dfs(int x, int maxn) {
    if ((n + 1) * x + h() >= maxn * (n + 1))
        return false;
    int cnt = 1;
    while (is_square[cnt] < 0 && cnt <= totsquare)
        cnt++;
    if (cnt > totsquare) {
        ans = min(x, ans);
        return true;
    }
    for (int i = 0; i < square[cnt].size(); ++i) {
        int num = square[cnt][i];
        if (link[num]) {
            for (int j = 0; j < stick[num].size(); ++j) {
                is_square[stick[num][j]]--;
            }
            link[num] = false;
            if (dfs(x + 1, maxn))
                return true;
            link[num] = true;
            for (int j = 0; j < stick[num].size(); ++j) {
                is_square[stick[num][j]]++;
            }
        }
    }
    return false;
}

int main() {
    std::ios::sync_with_stdio(false);
    int T;
    cin >> T;
    for (int kase = 1; kase <= T; ++kase) {
        memset(square, 0, sizeof(square));
        memset(stick, 0, sizeof(stick));
        cin >> n;
        m = 2 * n * (n + 1);
        int num, x;
        for (int i = 1; i <= m; ++i) {
            link[i] = true;
        }
        cin >> num;
        int neibor = 2 * n + 1;
        totsquare = 0;
        totstick = 2 * n * (n + 1);
        for (int sz = 1; sz <= n; sz++) {
            for (int i = 1; (i - 1) / neibor + sz <= n; i += neibor) {
                for (int j = i; j - i + sz <= n; j++) {
                    totsquare++;
                    for (int l = j; l - j < sz; l++) {
                        square[totsquare].push_back(l);
                        square[totsquare].push_back(l + sz * neibor);
                        stick[l].push_back(totsquare);
                        stick[l + sz * neibor].push_back(totsquare);
                    }
                    for (int l = j + n; (l - j - sz) / neibor < sz; l += neibor) {
                        square[totsquare].push_back(l);
                        square[totsquare].push_back(l + sz);
                        stick[l].push_back(totsquare);
                        stick[l + sz].push_back(totsquare);
                    }
                }
            }
        }
        memset(is_square, 0, sizeof(is_square));
        for (int i = 0; i < num; ++i) {
            cin >> x;
            link[x] = false;
            for (int j = 0; j < stick[x].size(); ++j) {
                is_square[stick[x][j]]--;
            }
            totstick--;
        }
        ans = INF;
        for (int i = 0; ; ++i) {
            if (dfs(0, i))
                break;
        }
        cout << ans << endl;
    }
    return 0;
}

/*
2
2
0
3
3 12 17 23
 */

你可能感兴趣的:(UVA,IDA)