Square Destroyer UVA

来源:互联网 发布:软件注册赚钱靠谱吗 编辑:程序博客网 时间:2024/06/05 10:41

题目传送门

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

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

#include <algorithm>#include <cmath>#include <cstdio>#include <cstring>#include <fstream>#include <iostream>#include <map>#include <queue>#include <set>#include <stack>#include <string>#include <vector>#include <sstream>#include <list>#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;}/*22033 12 17 23 */
原创粉丝点击