zoukankan      html  css  js  c++  java
  • POJ 1011Sticks

    http://poj.org/problem?id=1011&lang=default&change=true

      1 import java.io.BufferedReader;
      2 import java.io.InputStreamReader;
      3 import java.util.Arrays;
      4 import java.util.StringTokenizer;
      5 
      6 public class Main {
      7     static boolean[] used;
      8     static int len;
      9     static int[] s;
     10     static int sum;
     11     static int max;
     12     static int parts;
     13 
     14     public static void main(String[] args) throws Exception {
     15         BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
     16         while ((len = Integer.parseInt(reader.readLine())) != 0) {
     17             s = new int[len];
     18             StringTokenizer take = new StringTokenizer(reader.readLine());
     19             int index = 0;
     20             used = new boolean[len];
     21             sum = 0;
     22             while (take.hasMoreTokens()) {
     23                 s[index] = Integer.parseInt(take.nextToken());
     24                 sum += s[index++];
     25             }
     26             //对木棍长度进行排序
     27             Arrays.sort(s);
     28             max = s[len - 1];
     29             
     30             //木棒长度肯定是大于木棍长度的,必然从最长的开始进行合并
     31             for (; max <= sum; max++) {
     32                 //只有当木棒长度能够被sum整除时,该木棒长度才算合理
     33                 if (sum % max == 0) {
     34                     parts = sum / max;
     35                     //搜索按木棍长度,从大往小进行, 这样可以避免不变要的搜索
     36                     if (search(0, len - 1, 0)) {
     37                         System.out.println(max);
     38                         break;
     39                     }
     40                 }
     41             }
     42         }
     43     }
     44 
     45     /**
     46      * 尝试搜索使木棍能够凑成一个木棒
     47      * @param res 当前这在合成的木棒的已合成的长度
     48      * @param next 下一个需要搜索的木棍下标
     49      * @param cpl 已经合成的木棒数
     50      * @return 
     51      */
     52     private static boolean search(int res, int next, int cpl) {
     53         // res = max 说明当前已经合成一个木棒
     54         // cpl++    res置0    
     55         // next置为len-2, 因为此时len-1这个木棍肯定已经被用掉了,下次搜索肯定从len-2开始,其实这个并不重要,因为每次开始搜索的时候都会检查当前搜索的木棍used[next]
     56         if (res == max) {
     57             cpl++;
     58             res = 0;
     59             next = len - 2;
     60         }
     61         // 表明当前所有木棒已经合成完毕,返回
     62         if (cpl == parts) {
     63             return true;
     64         }
     65         
     66         // 当前还有木棍没有合并完,需进一步合并
     67         while (next >= 0) {
     68             // 如果当前木棍没有被使用过
     69             if (used[next] == false) {
     70                 // 已合并+ s[next】 <= max 说明当前木棍可以加入到当前正在合并的木棒中
     71                 if (res + s[next] <= max) {
     72                     used[next] = true;
     73                     // 搜索成功返回
     74                     if (search(res + s[next], next - 1, cpl)) {
     75                         return true;
     76                     }
     77                     // 搜索不成功,回溯
     78                     used[next] = false;
     79                     // 当前正在合并的木棒长度res = 0, 且剩余木棍中并不能再合成木棒,搜索失败
     80                     if (res == 0) {
     81                         break;
     82                     }
     83                     // 可以合成一个当前的,但是剩余的不能合成一个木棒,搜索失败
     84                     if (res + s[next] == max) {
     85                         break;
     86                     }
     87                     // 其他情况仍然可以搜索
     88                 }
     89 
     90                 int i = next - 1;
     91                 while (i >= 0 && s[i] == s[next]) {
     92                     i--;
     93                 }
     94                 next = i;
     95                 int l_s = 0;
     96                 while (i >= 0) {
     97                     if (!used[i]) {
     98                         l_s += s[i];
     99                     }
    100                     i--;
    101                 }
    102 
    103                 if (l_s < max - res) {
    104                     break;
    105                 }
    106                 continue;
    107             }
    108             next--;
    109 
    110         }
    111         return false;
    112     }
    113 
    114 }
  • 相关阅读:
    1046 Shortest Distance (20 分)(模拟)
    1004. Counting Leaves (30)PAT甲级真题(bfs,dfs,树的遍历,层序遍历)
    1041 Be Unique (20 分)(hash散列)
    1036 Boys vs Girls (25 分)(查找元素)
    1035 Password (20 分)(字符串处理)
    1044 Shopping in Mars (25 分)(二分查找)
    onenote使用小Tip总结^_^(不断更新中...)
    1048 Find Coins (25 分)(hash)
    三个故事
    领导者的举止
  • 原文地址:https://www.cnblogs.com/feiling/p/2743465.html
Copyright © 2011-2022 走看看