Poj Solution 2362

http://poj.org/problem?id=2362

import java.io.*;
import java.util.*;

public class Main {

//记录数字的总长度。
int totalNum;
//记录各个数字的值的数组。
int[] numArr;
//记录每个小短棒是否被使用过。
boolean[] used;

public static void main(String args[]) throws Exception {
   Main m=new Main();
   m.begin();
}

private void begin() throws Exception {
   Scanner cin = new Scanner(System.in);
   int totalLine = cin.nextInt();
   for(int i=0; i< totalLine; i++){
    totalNum = cin.nextInt();
    numArr = new int[totalNum];
    //总长度。
    int sumLen = 0;
    for(int j=0; j< totalNum; j++){
     numArr[j] = cin.nextInt();
     sumLen += numArr[j];
    }
    //初始化每个小短棒都没被使用过。
    used = new boolean[totalNum];
    for(int j=0; j< totalNum; j++)
     used[j] = false;
    //和必须时 4 的倍数。
    if(sumLen%4==0){
     //排序,逆序。
     Arrays.sort(numArr);
     int temp;
     for(int k=0; k< totalNum/2; k++){
      temp = numArr[k];
      numArr[k] = numArr[totalNum-1-k];
      numArr[totalNum-1-k] = temp;
     }
     //获得最大值。
     int maxNum = numArr[0];
     //重置已经拼好的边数为 0。
     passNum = 0;
     //最大值不能大于总长的 1/4。
     if(maxNum <= sumLen/4){
      //开始深度优先搜索。
      if(DFS(0, sumLen/4, 0))
       System.out.println("yes");
      else
       System.out.println("no");
     }else
      System.out.println("no");
    }else
     System.out.println("no");
   }
}

//记录已经拼出的符合长度的边的个数,最多 4 个。
int passNum = 0;
//参数分别是当前循环的标识符、要测试的长度、需要加上的底数。
private boolean DFS(int f_num, int f_len, int f_sum){
   //当底数和需要的长度相等时。
   if(f_len == f_sum){
    //增加一条通过的边数。
    passNum++;
    //重置底数和开始时标识符。
    f_sum = 0;
    f_num = 0;
    //当通过的边数和 4 相等就说明成功。
    if(passNum == 4)
     return true;
   }
   //开始遍历下一层。
   for(int i=f_num; i< totalNum; i++){
    //当底数加上本数小于等于需要的长度时,并且本数没被使用。
    if(f_sum+numArr[i]<=f_len && !used[i]){
     //暂时记录为已经使用。
     used[i] = true;
     //进行下一次的递归。
     DFS(i+1, f_len, f_sum+numArr[i]);
     //边数达到 4 后即可跳出循环。
     if(passNum == 4)
      break;
     //通过了上面的脚本,说明边数没有达到 4,而又能拼出一条边,取消掉这条边,以便测试其他的组合。
     if(f_sum+numArr[i] == f_len)
      passNum--;
     //取消本数的记录。
     used[i] = false;
    }
   }
   //退出时检查一次是否拼好正方形。
   if(passNum == 4)
    return true;
   //返回失败。
   return false;
}
}

											
This entry was posted in poj. Bookmark the permalink.