Stringinput=(String)list.get(i);
String[]strs=input.split("");
x[i]=Integer.parseInt(strs[0]);
y[i]=Integer.parseInt(strs[1]);
}
Arrays.sort(x);
Arrays.sort(y);
for(inttime=0;time<25;time++){
System.out.println(time+"时的最大访客数:
"+MaxVisit.maxGuest(x,y,time));
}
}
}
(8)洗扑克牌(乱数排列)
说明:
洗扑克牌的原理其实与乱数排列是相同的,都是将一组数字(例如1~N)打乱重新排列,只不过洗扑克牌多了一个花色判断的动作而已。
解法:
初学者通常会直接想到,随机产生1~N的乱数并将之存入阵列中,后来产生的乱数存入阵列前必须先检查阵列中是否已有重复的数字,如果有这个数就不存入,再重新产生下一个数,运气不好的话,重复的次数就会很多,程式的执行速度就很慢了,这不是一个好方法。
以1~52的乱数排列为例好了,可以将阵列先依序由1到52填入,然后使用一个回圈走访阵列,并随机产生1~52的乱数,将产生的乱数当作索引取出阵列值,并与目前阵列走访到的值相交换,如此就不用担心乱数重复的问题了,阵列走访完毕后,所有的数字也就重新排列了。
至于如何判断花色?
这只是除法的问题而已,取商数判断花色,取余数判断数字,您可以直接看程式比较清楚。
实现:
//java实现
publicclassShuffleCard{
publicstaticvoidmain(Stringargs[]){
finalintN=52;
int[]poker=newint[N+1];
//初始化阵列
for(inti=1;i<=N;i++)
poker[i]=i;
//洗牌
for(inti=1;i<=N;i++){
intj=(int)(Math.random()*N);
if(j==0)
j=1;
inttmp=poker[i];
poker[i]=poker[j];
poker[j]=tmp;
}
for(inti=1;i<=N;i++){
//判断花色
switch((poker[i]-1)/13){
case0:
System.out.print("桃");break;
case1:
System.out.print("心");break;
case2:
System.out.print("砖");break;
case3:
System.out.print("梅");break;
}
//扑克牌数字
intremain=poker[i]%13;
switch(remain){
case0:
System.out.print("K");break;
case12:
System.out.print("Q");break;
case11:
System.out.print("J");break;
default:
System.out.print(remain+"");break;
}
if(i%13==0)
System.out.println("");
}
}
}
(9)约瑟夫问题(JosephusProblem)
说明:
据说着名犹太历史学家Josephus有过以下的故事:
在罗马人占领乔塔帕特后,39个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。
然而Josephus和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。
解法:
约瑟夫问题可用代数分析来求解,将这个问题扩大好了,假设现在您与m个朋友不幸参与了这个游戏,您要如何保护您与您的朋友?
只要画两个圆圈就可以让自己与朋友免于死亡游戏,这两个圆圈内圈是排列顺序,而外圈是自杀顺序,如下图所示:
使用程式来求解的话,只要将阵列当作环状来处理就可以了,在阵列中由计数1开始,每找到三个无资料区就填入一个计数,直而计数达41为止,然后将阵列由索引1开始列出,就可以得知每个位置的自杀顺序,这就是约瑟夫排列,41个人而报数3的约琴夫排列如下所示:
1436138152243031634425175403161826737198352792032104121112839122233132923
由上可知,最后一个自杀的是在第31个位置,而倒数第二个自杀的要排在第16个位置,之前的人都死光了,所以他们也就不知道约琴夫与他的朋友并没有遵守游戏规则了。
实现:
//java实现
publicclassJosephus{
publicstaticint[]arrayOfJosephus(intnumber,intper){
int[]man=newint[number];
for(intcount=1,i=0,pos=-1;count<=number;count++){
do{
pos=(pos+1)%number;//环状处理
if(man[pos]==0)
i++;
if(i==per){//报数为3了
i=0;
break;
}
}while(true);
man[pos]=count;
}
returnman;
}
publicstaticvoidmain(String[]args){
int[]man=Josephus.arrayOfJosephus(41,3);
intalive=3;
System.out.println("约琴夫排列:
");
for(inti=0;i<41;i++)
System.out.print(man[i]+"");
System.out.println("\nL表示3个存活的人要放的位置:
");
for(inti=0;i<41;i++){
if(man[i]>(41-alive))
System.out.print("L");
else
System.out.print("D");
if((i+1)%5==0)
System.out.print("");
}System.out.println();
}
}
(10)排列组合
说明:
将一组数字、字母或符号进行排列,以得到不同的组合顺序,例如123这三个数的排列组合有:
123、132、213、231、312、321。
解法:
可以使用递回将问题切割为较小的单元进行排列组合,例如1234的排列可以分为1[234]、2[134]、3[124]、4[123]进行排列,这边利用旋转法,先将旋转间隔设为0,将最右边的数字旋转至最左边,并逐步增加旋转的间隔,例如:
1234->旋转1->继续将右边234进行递回处理
2134->旋转12变为21->继续将右边134进行递回处理
3124->旋转123变为312->继续将右边124进行递回处理
4123->旋转1234变为4123->继续将右边123进行递回处理
实现:
//java实现
publicclassPermutation{
publicstaticvoidperm(int[]num,inti){
if(ifor(intj=i;j<=num.length-1;j++){
inttmp=num[j];
//旋转该区段最右边数字至最左边
for(intk=j;k>i;k--)
num[k]=num[k-1];
num[i]=tmp;
p