虫子爬杆问题,使用迭代。


package test3;

import java.util.ArrayList;
import java.util.Collections;;

/**
* 问题描述:
* 一根长27CM棍上有5只虫分布在 3,7,11,17,23CM 的位置上。虫子们都在一条直线上爬,碰到了就掉头。
* 求所有虫子都爬出去所需的最长和最短时间。
* 解题思路:
* 只要每条虫子的方向确定,虫子们都爬出去的时间就确定。
* 1条虫子有2个方向,可以看做能取2个值0,1。那5条虫子就是5个取0,1的位的组合,即2的5次方种组合方法。
* 用0-31的整数转成2进制表示所有方向方向。
* @author 杨佳
*
*/
public class WormTest {
public static int slong = 27;//49;
public static int[] wormArr = {3,7,11,17,23};//{3,7,11,17,23,33,37,43};
/**
* @author 杨佳
* @param args
*/
public static void main(String[] args) {
ArrayList<Integer> timeList = new ArrayList<Integer>();
for(int i=0;i<Math.pow(2,wormArr.length);i++){
timeList.add(getUseTime(i,wormArr));
}
Collections.sort(timeList);
System.out.println("min:"+timeList.get(0));
System.out.println("max:"+timeList.get(timeList.size()-1));

//虫子相撞是否掉头 对 所有虫子都爬出去所用的时间 没有影响 ,所以有以下简单方法
int hafe = slong/2;
ArrayList<Integer> newList = new ArrayList<Integer>();
for(int i=0;i<wormArr.length;i++){
if(wormArr[i]>hafe){
newList.add(slong - wormArr[i]);
}else{
newList.add(wormArr[i]);
}
}
Collections.sort(newList);
System.out.println("min2:"+newList.get(newList.size()-1));
System.out.println("max2:"+Math.max(Math.max(wormArr[0],slong-wormArr[0]),Math.max(wormArr[wormArr.length-1],slong-wormArr[wormArr.length-1])));
}

public static int getUseTime(Integer aspect,int[] wormsInit){
int[] worms = wormsInit.clone();
int time = 0;

//先把方向处理成数组
int[] aspectArr = processAspect(aspect,worms.length);

if(worms.length == 0){//同时移出为0,有偶数个虫子时可能发生这种情况
time += 0;
}else if(worms.length == 1){
time += Integer.toBinaryString(aspect).equals("1")?slong-worms[0]:worms[0];
}else{
int newAspect = 0;
int[] newWormArr = null;
while(true){
boolean flag = false;

//按方向走
//先判断是否有虫子已经出去,若出去了,移除数组中的0和对应的方向位 重新生成方向值
ArrayList<Integer> zeroValue = new ArrayList<Integer>();
for(int i=0;i<worms.length;i++){
worms[i] += aspectArr[i];
if(worms[i]==0||worms[i]==slong)zeroValue.add(i);
}
if(zeroValue.size()>0){
flag = true;
//新数组
int leftnum = worms.length - zeroValue.size();
newWormArr = new int[leftnum];
int j=0;
for(int i=0;i<worms.length;i++){
if(worms[i]!=0&&worms[i]!=slong){
newWormArr[j] = worms[i];
j++;
}
}
//新方向值
newAspect = getNewAspect(aspect,zeroValue,worms.length);
}else{
newWormArr = worms;
newAspect = aspect;
}
//再判断是否发生碰撞(即判断 相邻2个是否相等),如果碰撞方向位置反,重新生成方向值(如果有重新生成数组或方向值要跳出循环)
ArrayList<Integer> hitList = new ArrayList<Integer>();
for(int i=0;i<newWormArr.length-1;i++){
int ifHit = new Integer(newWormArr[i]).compareTo(new Integer(newWormArr[i+1]));
if(ifHit == 0){
hitList.add(i);
hitList.add(i+1);
}
}
if(hitList.size()>0){
flag = true;
newAspect = getChangeAspect(newAspect,hitList,newWormArr.length);

}

//每循环一次时间++
time++;
if(flag == true){
break;
}
}
time += getUseTime(newAspect,newWormArr);
}

return time;
}

private static int getChangeAspect(int newAspect, ArrayList<Integer> hitList,int length) {
StringBuffer sb = new StringBuffer(Integer.toBinaryString(newAspect));
while(sb.length()<length){
sb.insert(0,0);
}
//System.out.println(sb);
char[] aspectChars = sb.toString().toCharArray();
char[] newChars = new char[aspectChars.length];
for(int i=0;i<aspectChars.length;i++){
if(test(i,hitList)){
newChars[i] = aspectChars[i]=='0'?'1':'0';
}else{
newChars[i] = aspectChars[i];
}
}
return Integer.parseInt(new String(newChars),2);
}

//新方向生成
private static int getNewAspect(Integer aspect, ArrayList<Integer> zeroValue,int length) {
StringBuffer sb = new StringBuffer(Integer.toBinaryString(aspect));
while(sb.length()<length){
sb.insert(0,0);
}
//System.out.println(sb);
char[] aspectChars = sb.toString().toCharArray();
char[] newChars = new char[aspectChars.length-zeroValue.size()];
int j=0;
for(int i=0;i<aspectChars.length;i++){
if(test(i,zeroValue))continue;
newChars[j] = aspectChars[i];
j++;
}
//最后2个同时移出的时候 以下值可能为空
String ass = new String(newChars);
if(ass.equals(""))return 0;
return Integer.valueOf(ass, 2);
}

private static boolean test(int index ,ArrayList<Integer> zeroValue){
for(int i : zeroValue){
if(index == i)return true;
}
return false;
}

//处理方向成数组 设定:0表示负方向,1表示正方向
private static int[] processAspect(Integer aspect,int length) {
int[] aspectArr = new int[length];
StringBuffer sb = new StringBuffer(Integer.toBinaryString(aspect));
while(sb.length()<length){
sb.insert(0, 0);
}
for(int i=0;i<aspectArr.length;i++){
aspectArr[i] = new Integer(String.valueOf(sb.charAt(i))) == 1?1:-1;
}

return aspectArr;
}


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值