HDU 1518 Square(Dfs)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1518

 

题意:给你n条边,问你用光这些边能不能组成正方形

 

想到用深搜,但是怎么写出来挺难的。。。。。

 

这里主要是超时问题:其实对于某条边,对于那些用过的和不符合条件的for那里可以不扫。。。。。所以Dfs要增加一个参数index表示从那里开始扫。。。但是换另外一条边的时候index要改回0,因为那些未用的,对上一条边来说

不符合条件的,可能符合这条边的条件。。。。

 

代码:

#include <iostream>
using namespace std;

const int M = 10000;

int save[M];
bool used[M];
int sum;
int l;
int n;
int flag;

void Dfs(int now, int len, int index)//now:第几条边  len:该边现在组成的长度 index:用来优化时间
{
    

    if (now == 5)
    {
        flag = 1;
        return ;
    }

    if (len == l)
    {
        Dfs(now + 1, 0, 0);
        if (flag)//优化时间
        {
            return ;
        }
    }

    for (int i = index; i < n; i++)//从index开始优化时间
    {
        if (!used[i] && save[i] + len <= l)
        {
            used[i] = 1;
            Dfs(now, save[i] + len, i + 1);
            if (flag)//优化时间
            {
                return;
            }
            used[i] = 0;
        }
    }
}

int main()
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        
        sum = 0;
        scanf("%d", &n);
        for (int i = 0; i < n; i++)
        {
            scanf("%d", save + i);
            sum += save[i];
        }
        
        if (sum % 4 != 0)//简答的优化
        {
            puts("no");
            continue;
        }


        l = sum / 4;

        int i;
        for (i = 0; i < n; i++)//有比边长大的边就不行
        {
            if (save[i] > l)
            {
                break;
            }
        }
        if (i != n)
        {
            puts("no");
            continue;
        }


        memset(used, 0, sizeof(used));
        flag = 0;
        Dfs(1, 0, 0);

        if (flag)
        {
            puts("yes");
        }
        else
        {
            puts("no");
        }
    }
    return 0;
}

 

 

posted on 2012-09-02 22:49  [S*I]SImMon_WCG______*  阅读(754)  评论(0编辑  收藏  举报

导航