uva10570---外星人聚会(meeting with aliens)

这道题刚开始做的时间没有思路,后来看了别人的思路后,写了自己的代码。

举例介绍:有向环

比如一组数据{5,4,3,2,1}; 如果按照正向排序,各个位置的下标为1,2,3,4,5,那么有向环为{5,1}{4,2}{3}一个3个。

思路:其实本道题就是找有向环,假如说有向环的数量为m,则需要交换的次数就为Array.size - m.同时本道题应该分为顺时针编号和逆时针编号,分别假定各个位置为其实位置,求有向环的个数,那么交换最少的次数便为Array.size- max(m)

代码1(我原始的思路,只是求出了2个方向,所有位置为起点的有向环的数量):

import java.util.Arrays;

public class MeettingWithAlien {
	//uva  10570  外星人聚会
	//0,5,2,3,4,1          0,5,4,3,2,1
	private static int[] data = {0,5,2,3,4,1};
	private static int[] visit = new int[data.length]; // 记录该位置是否已经被访问过
	public static void main(String[] args) {
		System.out.println("正序");
		for (int i=1; i<data.length; i++){
			System.out.println(getCircle(i));	
		}
		
		System.out.println("逆序");
		for (int i=1; i<data.length; i++){
			System.out.println(getCircle2(i));	
		}
		
	}
	
	public static int getCircle2(int flag){//flag代表是 该位置是1号位置
		int circleCount = 0;  //用于 记录环的数量
		Arrays.fill(visit, 0);
		int position = 0;    //当设置起点的时候,记录当前i在环中的真实位置
		for (int i=1; i<data.length; i++){
			position = getPosition2(flag, i); //当从新确定起点后,得到当前位置的真实位置
				//看该位置value =index相等,同时保证该元素没有被访问过 
			if (visit[i] == 0 && position == data[i]){
				 ++circleCount;
				 visit[i] = 1;
			}else if (visit[i] == 0 && position != data[i]){
				//如果该位置的元素没有被访问过,同时呢,该位置的value != index,那么dp寻找属于该环的元素 
				++circleCount;
				 dp2 (data[i],flag);
			}
		}
		return circleCount;
	}
	
	public static int getCircle(int flag){//flag代表是 该位置是1号位置
		int circleCount = 0;  //用于 记录环的数量
		Arrays.fill(visit, 0);
		int position = 0;    //当设置起点的时候,记录当前i在环中的真实位置
		for (int i=1; i<data.length; i++){
			position = getPosition(flag, i); //当从新确定起点后,得到当前位置的真实位置
			//看该位置value =index相等,同时保证该元素没有被访问过 
			if (visit[i] == 0 && position == data[i]){
				 ++circleCount;
				 visit[i] = 1;
			}else if (visit[i] == 0 && position != data[i]){
				//如果该位置的元素没有被访问过,同时呢,该位置的value != index,那么dp寻找属于该环的元素 
				++circleCount;
				 dp (data[i],flag);
			}
		}
		return circleCount;
	}
	
	public static int getPosition(int m, int n){ //该函数的作用是如果指定m号位置为1号位置,那么n号位置应该为几号
		
		if (n >= m){
			return n - m + 1;
		}else {
			return n + data.length - m;
		}
	}
	
	public static int getPosition2(int m,int n){  //当数数的方向为逆时针的时候
		if (n > m){
			return m + data.length - n;
		}else {
			return 1 + (m-n);
		}
	}
	
	public static void dp (int n, int flag){ //flag代表的是编号为1的位置,
		int position = flag + n - 1;
		if (position >= data.length){
			position = position - data.length + 1; 
		}
		if (visit[position] == 1){
			return;
		}else {
			
			visit[position] = 1;
			dp(data[position], flag);
		}
	}
	
	public static void dp2 (int n, int flag){ //flag代表的是编号为1的位置,
		int position = flag - n + 1;
		if (position <= 0){
			position = flag - n + data.length;
		}
		if (visit[position] == 1){
			return;
		}else {
			visit[position] = 1;
			dp2(data[position], flag);
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值