源地址为: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); } }