【转】POJ-2362-Square:简单 DFS+剪枝

思路:

首先将输入的各边长累加求和 即四边形周长sum, 后除4 即边长side,这样 通过DFS 搜索这些sticks能否组合成4根长度均为side 进而确定yes no。

在此 就涉及到搜索顺序了-最优性剪枝: 不难理解 先搜索的小棒子 越长,组合构成side的方式就越少,搜索到结果的时间就越短。

SO从最长的棒子开始进行DFS。

// num表示已确认组合构成 的side的数目 即所求正方形的边数
// len表示所求正方形边长度 s表示搜索起点

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

int N, M, sum, side;

bool DFS(int *sticks, bool *visited,         int num, int len, int s)
{
    if(num==3)//最优性剪枝 当搜索到3条边都满足时停止搜索
        return true;

    for(int i=s; i>=0; i--)
    {
        if(visited[i])
            continue;

        visited[i]=true;
        if(len+sticks[i]<side)
        {
            if(DFS(sticks,visited,num,len+sticks[i],i))
                return true;
        }
        else if(len+sticks[i]==side)
        {
            if(DFS(sticks,visited,num+1,0,M-1))
                return true;
        }
        visited[i]=false;// 回溯 该边不满足当前side的组合
    }
    return false;
}

int main()
{
    cin>>N;
    while(N--)
    {
        cin>>M;
        sum=0;
        int *sticks=new int[M];
        bool *visited=new bool[M];

        for(int i=0; i<M; i++)
        {
            cin>>sticks[i];
            visited[i]=false;
            sum+=sticks[i];
        }
        sort(sticks,sticks+M);

        side=sum/4;
        if(sum%4!=0||sticks[M-1]>side)//可行性剪枝
        {
            cout<<"no"<<endl;
            continue;
        }
        memset(visited,0,sizeof(visited));
        if(DFS(sticks,visited,0,0,M-1))
            cout<<"yes"<<endl;
        else
            cout<<"no"<<endl;

        delete sticks;
        delete visited;
    }
    return 0;
}

  

时间: 2024-10-29 19:08:45

【转】POJ-2362-Square:简单 DFS+剪枝的相关文章

DFS POJ 2362 Square

题目传送门 1 /* 2 DFS:问能否用小棍子组成一个正方形 3 剪枝有3:长的不灵活,先考虑:若根本构不成正方形,直接no:若第一根比边长长,no 4 这题是POJ_1011的精简版:) 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <cstring> 9 #include <map> 10 #include <set> 11 #include <cmath>

poj 1724:ROADS(DFS + 剪枝)

ROADS Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10777   Accepted: 3961 Description N cities named with numbers 1 ... N are connected with one-way roads. Each road has two parameters associated with it : the road length and the toll

POJ - 1011 - Sticks (DFS + 剪枝)

题目传送:Sticks 思路:DFS + 剪枝 AC代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <vector> #include <map> #include

POJ 2362:Square(DFS)

问所给木棒能否构成一个正方形 难点在于木棒可以拼接,比如2 2 1 1 2也是能构成正方形的 这题的剪枝有点意思: 第一是提前判断所给的木棒长度之和能否被4整除,不能直接输出NO 第二是只需满足上面的条件后,只需要找到3条边就行了,剩下一条边自然也符合 l表示已找到的长度,cnt为已找到的边 #include"cstdio" #include"cmath" #include"cstring" #include"algorithm&quo

POJ 2362 Square

题意:给n个木棍,问能不能正好拼成一个正方形. 解法:POJ1011的简单版……不需要太多剪枝……随便剪一剪就好了……但是各种写屎来着QAQ 代码: #include<stdio.h> #include<iostream> #include<algorithm> #include<string> #include<string.h> #include<math.h> #include<limits.h> #include&

HDU 1518 Square (DFS+剪枝)

Given a set of sticks of various lengths, is it possible to join them end-to-end to form a square? Input The first line of input contains N, the number of test cases. Each test case begins with an integer 4 <= M <= 20, the number of sticks. M intege

POJ 1011 Sticks 【DFS 剪枝】

题目链接:http://poj.org/problem?id=1011 Sticks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 154895   Accepted: 37034 Description George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now

poj 1011/2362 dfs+剪枝(拼木棍)

题意:乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位.然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度.请你设计一个程序,帮助乔治计算木棒的可能最小长度.每一节木棍的长度都用大于零的整数表示.(2362是1011的特例,问一堆木棍能否拼成正方形) 思路:dfs+剪枝.其中剪枝具有相当的技巧性,其中一个地方的剪枝没有想到导致tle多次. 几个明显的剪枝点(设ans为最终的答案): 1.ans>=这堆木棍的最大长度 2.ans

poj 1011 Sticks 【DFS】+【剪枝】

题意:有未知根(长度一样)木棒(小于等于n),被猪脚任意的截成n段,猪脚(脑抽了)想知道被截之前的最短长度(我推测猪脚得了健忘症). 这道题光理解题意就花了好久,大意就是任意根被截后的木棒拼到一起,能不能组成s(<=n)根的相同的木棒, 例:数据 9  5 1 2 5 1 2 5 1 2 可以组成最短为6 的(5+1, 2+2+2)3根木棒. 策略:深搜. 不过要是传统的深搜的话,TLE妥妥的.所以要剪枝(所谓剪枝,就是多加几个限制条件). 话不多说直接上代码. 代码1: #include <