木棍拼正方形 Stick To Square

木棍拼正方形 Stick To Square

一个整数组sticks代表一堆木棍的长度,木棍不能折断,但是可以连接。每一个木棍都要使用到。判断给的木棍能否拼成一个正方形。

sticks= [1,1,2,2,2]
out:true

思路

使用DFS

首先,对数组做一个非递减排序。计算所有木棍长度和sum。如果sum%4!=0,说明无法拼成一个正方形。

否则进入dfs,准备寻找可能的方案。建立一个数组arr保存每条边剩余需要木棍的长度。

总共有n个木棍,从最长的第n个木棍开始向前处理,设定如果走完所有的木棍,ind==-1时,找到了正确的方案。

循环 对4条边尝试放入第ind个木棍,如果arr[i]<ms[ind],说明木棍比这个边剩余的长度还长,不能放在arr[i],寻找下一个i。否则就会出现2个情况,

  1. arr[i]==ms[ind] 木棍长度刚好等于第i个边剩余的长度,arr[i]-=ms[ind],然后继续dfs,此时要处理的是ms[ind-1]。
  2. arr[i]>ms[ind] 木棍长度刚好大于第i个边剩余的长度,但是如果大于的话,说明要满足正方形方案的话,还要一个ms[?]来填。此时ms[0]是最小的木棍,如果不满足arr[i]>=ms[ind]+ms[0],说明arr[i]是无法通过ms[ind]配合其他木棍来填的。

通过上面的2个情况来缩小dfs的分支。

public boolean makesquare(int[] sticks) {
    
    
        Arrays.sort(sticks);// s to l

        int sum =0;
        for(int i=0;i<sticks.length;i++){
    
    
            sum+= sticks[i];
        }
        if(sum%4!=0){
    
    
            return false;
        }
        int[] arr = new int[4];
        for(int i=0;i<arr.length;i++){
    
    
            arr[i]=sum/4;
        }
        return dfs(sticks.length-1,arr,sticks);
    }
    public boolean dfs(int ind ,int[] arr,int[] ms){
    
    
        if(ind==-1){
    
    
            return true;
        }
        for(int i = 0;i<4;i++){
    
    
            if(arr[i]<ms[ind]){
    
    
                continue;
            }
            if(arr[i]==ms[ind]||arr[i]>=ms[ind]+ms[0] ){
    
    
                arr[i]-=ms[ind];
                if(dfs(ind-1,arr,ms)){
    
    
                    return true;
                }
                arr[i]+=ms[ind];
            }
        }
        return false;
    }

Tag

DFS

おすすめ

転載: blog.csdn.net/edisonzhi/article/details/120643404