UVA101 java

1.三个数组,大小n+1防止越界
  posi[]:存放0~n-1号木块当前所在位置(在哪一堆)
  num[]:存放0~n-1号堆,当前所包含的木块的数量
  ans[][]:二维数组每一行,代表一个堆
2.观察可以发现
  如果为move,将a上方的木块归位
  如果为onto,将b上方的木块归位
3.最重要的一点!!如果a和b在同一堆,就什么也不做!!
import java.util.Arrays;
import java.util.Scanner;

public class Main {
	static int[] posi;
	static int[] num;
	static int[][] ans;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n=sc.nextInt();//次数
		posi=new int[n+1];//每个数字木块的位置
		num=new int[n+1];//每个队列对应的木块数量
		ans=new int[n+1][n+1];
		for (int i = 0; i < ans.length; i++) {
			posi[i]=i*10000;//横坐标*10000+纵坐标
			Arrays.fill(ans[i], -1);//所有地方都初始化为-1
			ans[i][0]=i;//初始化,第一个队列为对应序号木块,0号队列0木块,1号队列1木块。。。
			num[i]=1;//每个队列暂时都只有1个木块
		}
		sc.nextLine();//吃掉换行符
		while(true) {
			String cur=sc.nextLine();//读取每一个指令
			String[] split = cur.split(" ");
			if(split[0].equals("quit"))break;
			String com_a=split[0];
			int a=Integer.parseInt(split[1]);
			String com_b=split[2];
			int b=Integer.parseInt(split[3]);
			int x_a=posi[a]/10000;//得到a的横坐标
			int y_a=posi[a]%10000;//得到a的纵坐标
			int x_b=posi[b]/10000;//得到b的横坐标
			int y_b=posi[b]%10000;//得到b的纵坐标
			if(x_a==x_b) {
				
				continue;
			}else {
				if(com_a.equals("move")) {//将a上方的木块归为
					back(a);
				}
				if(com_b.equals("onto")) {//将b上方的木块归为
					back(b);
				}
				for (int i = y_a; i < n; i++) {
					int t=ans[x_a][i];
					if(t==-1 || (x_a==x_b && com_a.equals("pile") && com_b.equals("over")))break;
					ans[x_a][i]=-1;
					num[x_a]--;
					ans[x_b][num[x_b]]=t;
					posi[t]=x_b*10000+num[x_b];
					num[x_b]++;
				}
			}
			
		}
		for (int i = 0; i < n; i++) {
			System.out.print(i+":");
			for (int j = 0; j < num[i]; j++) {
				System.out.print(" "+ans[i][j]);
			}
			System.out.println();
		}
		
	}

	private static void back(int k) {//归位
		int x=posi[k]/10000;
		int y=posi[k]%10000;
		for (int i = y+1; i < ans.length; i++) {
			int cur=ans[x][i];
			if(cur==-1)break;
			ans[x][i]=-1;
			num[x]--;
			ans[cur][num[cur]]=cur;
			posi[cur]=cur*10000+num[cur];
			num[cur]++;
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值