zoukankan      html  css  js  c++  java
  • 棍子Sticks(poj_1011)[经典搜索]

    【题意描述】

        George用相同的长度棍子,将他们随机切成最多64个单位的长度,现在,他想回到原来的状态,但他忘了他原来的多少根,以及他们原本是多长。请帮助他和设计一个程序,计算最小的可能的原始长度。所有长度均大于零的整数。

    【输入】

       输入包含2行的块。第一行:切成多少根,最多有64根。第二行切成的每一根的长度。文件的最后一行包含零,表示结束。

    【输出】

      输出每行应包含原始棒的最小可能长度。

    【输入样例】

    9
    5 2 1 5 2 1 5 2 1
    4
    1 2 3 4
    0

    【输出样例】

    6
    5


    附源文件如下:
     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 using namespace std;
     5 const int Max = 65;
     6  
     7 int n, len, stick[Max];
     8 bool flag, vis[Max];
     9 
    10 bool cmp(int a, int b)  //排序从大到小的比较函数 
    11 {
    12     return a > b;
    13 }
    14 
    15 void dfs(int dep, int now_len, int u)
    16 {
    17     if(flag) return;
    18      if(now_len == 0)           //目前长度为0,也就是说重新开始 
    19      {                    
    20         int k = 0;
    21         while(vis[k]) k ++;              
    22         vis[k] = true;
    23         dfs(dep + 1, stick[k], k + 1);
    24         vis[k] = false;
    25         return;
    26     }
    27      if(now_len == len)
    28      {                  //  当前长度为len,即又拼凑成了一根原棒
    29         if(dep == n) flag = true;        //  完成的标志:所有的n根小棒都有拼到了
    30         else dfs(dep, 0, 0);
    31         return;
    32     }
    33     for(int i = u; i < n; i ++)
    34         if(!vis[i] && now_len + stick[i] <= len)
    35         {
    36             if(!vis[i-1] && stick[i] == stick[i-1]) continue;      //  不重复搜索:最重要的剪枝
    37             vis[i] = true;
    38             dfs(dep + 1, now_len + stick[i], i + 1);
    39             vis[i] = false;
    40         }
    41 }
    42 
    43 int main()
    44 {
    45     freopen("p.in","r",stdin);
    46     freopen("p.out","w",stdout);
    47     while(scanf("%d", &n) && n != 0)
    48     {
    49         int sum = 0;
    50         flag = false;
    51         for(int i = 0; i < n; i ++)
    52         {
    53             scanf("%d", &stick[i]);
    54             sum += stick[i];
    55         }
    56         sort(stick, stick + n, cmp);     //  从大到小排序
    57         
    58          for(len = stick[0]; len < sum; len ++)
    59             if(sum % len == 0)
    60             {                                       //  枚举能被sum整除的长度
    61                 memset(vis, 0, sizeof(vis));       //注意只能在这里进行初始化 
    62                 dfs(0, 0, 0);
    63                 if(flag) break;
    64             }
    65         printf("%d
    ", len);
    66     }    
    67     return 0;
    68 }
  • 相关阅读:
    SQL 代码片段
    SQL
    Python List
    python_enumerate用法
    HashMap记录
    Brute Force(暴力算法)
    python解析html文件,提取标签中一个元素
    每五分钟统计一次数据
    grep
    expect
  • 原文地址:https://www.cnblogs.com/jjzzx/p/5264195.html
Copyright © 2011-2022 走看看