现在的位置: 首页 > 综合 > 正文

poj1011

2013年07月19日 ⁄ 综合 ⁄ 共 663字 ⁄ 字号 评论关闭

题目:http://poj.org/problem?id=1011

这题我莫名其妙的0ms过的,本来是用discuss那个测试数据,跑半天都没有结果,然后看到有一个人思路跟我很像,就把他的用来试试那组坑人的数据,结果也是跑半天都没有结果,我把他的提上去居然A了,32ms,然后就提提我的,居然0ms。好吧,还是poj的数据太弱
题意就是有一堆木棍,然后要把它们拼凑成长度一样的。并要求这个长度是满足条件最小的
思路,对满足能跟整除所有木棍之和的长度进行枚举,然后进行深搜,dfs(int len, int num, int cur_len);//这里三个参数的意思是len是搜索的长度,num是已经搜索的木棍的个数,cur_len当前正在拼凑的木棍的长度。然后对于没有使用过的木棍i,如果cur_len + stick[i] <= len 就把该木棍标记为已经选上去,重点不是搜索啦,而是剪枝 代码:

#include<cstdio>
#include<algorithm>
using namespace std;
int N, sum;
int stick[64];
 
bool cmp(int a, int b) {//对stick进行升序排列,这样可以减少递归次数
    return a > b;
}
 
bool dfs(int len, int num, int cur_len) {
    if(num == N) {//已经搜索到第N根木棍直接返回,不需要管这时的cur_len是否跟len相等。因为已经有前提sum%len == 0,前N-1 根找出来了,剩下的肯定能找出来,所以直接返回就ok
        return true;
    }
    if(cur_len == len) {//正在拼凑的木棍昌墩为len了,就把它初始化为0,表示已经拼凑完一根木棍
        cur_len = 0;
    }
    for(int i = 0; i < N; ++ i) {
        if(stick[i] != 0) {//这里偷了一下懒,懒得用visited,直接stick[i] == 0表示这根木棍被用过了
            if(cur_len + stick[i] <= len) {
                int temp = stick[i];//暂时记录,后面回溯时用到
                stick[i] = 0;
                if(dfs(len, num + 1, cur_len + temp)) {//搜索成功就直接返回
                    return true;
                }
                stick[i] = temp;//回溯
                if(cur_len + temp == len || cur_len == 0) {//剪枝,是表示如果当前这根木棍正好可以拼凑成一个len长度,或者正在进行一根新的木棍的拼凑,但搜索还是失败了,说明这次搜索的结果就是失败的,所以直接退出
                    break;
                }
                while(i < N - 1 && stick[i] == stick[i + 1]) {//这根不行的话,跟它长度一样的也就不行
                    i++;
                }
            }
        }
    }
    return false;
}
 
int main() {
    freopen("poj1011.txt", "r", stdin);
    while(scanf("%d", &N), N) {
        sum = 0;
        for(int i = 0; i < N; ++ i) {
            scanf("%d", &stick[i]);
            sum += stick[i];
        }
        sort(stick, stick + N, cmp);
        for(int len = stick[0]; len <= sum; ++ len) {
            if(sum % len == 0) {
                bool flag = dfs(len, 0, 0);
                if(flag) {
                    printf("%d\n", len);
                    break;
                }
            }
        }
    }
}

抱歉!评论已关闭.