CSDN論壇上的一道算法題

源地址爲:http://bbs.csdn.net/topics/390854089java

昨天晚上在CSDN論壇上看到這道題,思索一番後想到一個解決方案,也簡單實現了。今天早上把博客補一補。算是作個筆記吧。算法

題目:函數

有m我的面向南方站成一排(m ≥1),每喊一次口號能夠有n我的同時轉身一次(1≤n≤m),問共需喊多少次口號全部人最終所有面向北方?
請編寫一個函數,函數有兩個參數,分別爲m和n,函數返回值爲最終須要的次數,若通過無窮大次仍然沒法所有轉向北方,則輸出-1.
例1:
m = 6,n =5:
用0表示面向南方,1表示面向北方,過程以下:人工智能

0 0 0 0 0 0
0 1 1 1 1 1
1 1 0 0 0 0
0 0 0 1 1 1
1 1 1 1 0 0
0 0 0 0 0 1
1 1 1 1 1 1

返回6
例2:
m = 3,n = 2:
返回-1spa

 

關注這個帖子的人還蠻多的,很多人都或完整或不完整的給出了本身的方案。這些方案集中在尋找這個問題的公式解。.net

在還沒看下面的回答以前,我思考了一下,與大部分網友不一樣的是,從一開始我就沒想要找到這個問題的公式解。我發現這本質上是一個搜索問題。爲何這麼說,且看下面的分析。code

1.這m個數其實沒有位置之分,m的數的狀態能夠用0和1的個數來標記。blog

2.一旦指定m,m就不會再變化了,因此甚至能夠只用0的個數來標記狀態,在這裏我用全部m個數的和來標記狀態(1的個數)。get

3.每一次變化n個數,至關於向前搜索。用x表示0的個數,用y表示1的個數。變化n個數對m個數和的影響就是加上一個數。這個數可能有多種可能,取值的上限和0的個數有關,下限和y的個數有關。用max和min來表示上限和下限,具體來講,當x>=n時,max = n;當x<n時,max = x - (n - x) = 2x - n;當y>=n時,min = -n;當y< n 時,min = n - 2y。博客

4.人工智能課上介紹的搜索算法有不少,BFS,DFS,A-star之類的。BFS可以獲得最優解,可是時間、空間開銷可能比較大,DFS可能在短期內找到解,但不能保證是最優的,A-star有不少優勢,解是最優的,速度也快,但是須要啓發式函數。這裏我採用BFS。

下面是個人代碼:

import java.util.ArrayList;
import java.util.Iterator;

import javax.management.openmbean.ArrayType;
import javax.management.openmbean.SimpleType;

public class OneAlgorithm {

    /**
     * 
     * @param x: x is number of zeros
     * @param y: y is number of ones 
     * @return
     */
    public static int max(int x, int y, int n){
        int max = 0;
        if(x >= n)
            max = n;
        else
            max = 2 *x - n;
        
        return max;
    }
    
    public static int min(int x, int y, int n){
        int min = 0;
        if(y >= n)
            min = -n;
        else
            min = n - 2*y;
        
        return min;
    }
    
    /**
     * 
     * @param m
     * @param n
     * @return
     */
    public static int BFS(int m, int n){
        if(m % n == 0)
            return n;
        
        ArrayList<Integer> states = new ArrayList<Integer>();
        ArrayList<Integer> floors = new ArrayList<Integer>();
        int floor = 0;
        int zeros = m;
        floors.add(floor);
        states.add(zeros);
        
        int index = 0;
        
        int max, min;
        int x = m;
        int y = 0;
        max = max(x,y,n);
        min = min(x,y,n);
        
        while(true){
            while(max >= min)
            {
                zeros = x - min;
                if(zeros == 0)
                    return floors.get(index)+1;
                if(floors.indexOf(index) == floor)
                    floor++;
                if(!states.contains(x-min))
                {
                    states.add(x-min);
                    floors.add(floor);    
                }
                min = min + 2;
            }    
            index = index + 1;
            if(index+1 > states.size())
                return -1;
            x = states.get(index);
            y = m - x;
            max = max(x,y,n);
            min = min(x,y,n);
        }
    }
    
    public static void main(String[] args){
        int temp = BFS(13,7);
        System.out.println(temp);
    }
}
相關文章
相關標籤/搜索