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;

}

 

 

你可能感兴趣的:(HDU)