Java笔试题:老师带学生过河

题目描述:有n个老师和n个学生,n个老师要带n个学生过河,要求一个老师带一个学生,即老师要在学生前面,学生不能单独过河,求出所有的合法组合。T代表老师,C代表学生,按字母顺序输出

输入范例

2

输出范例

TCTC

TTCC

 

分析:

这题类似求多重括号是否合法,例如((()))是合法的,而(()))(则是非法的

可以用二进制的方式表示,T代表1,C代表0

判断是否合法的方法是定义一个变量,变量遇到1则加1,遇到0则减1,遍历完成时变量的值为0才是合法的,如果变量在某一刻出现为负数,那么肯定是不合法的,可以直接返回了

 

题目要求n个学生和n个老师,那么表示的二进制数必须是2n位的(第一位必须是1)

二进制为2n位的最小值规律:

n=1 ,10B = 2^1

n=2,1000B = 2^3

n=3,100000B  = 2^5

……

综上,可以得出n=k,最小值为2^(2k-1)

那么最大值又是多少呢?是全部为1吗(2^2n-1)?

当然不是啦,前面1的数最多只能有n位

例如n=2,那么到1100就应该停止了

最大值规律:

n=1,10B  = 2^1

n=2,1100B = 2^2+2^1

n=3,111000B = 2^5+2^4+2^3

n=4,111110000B = 2^7+2^6+2^5+2^4

……

综上,可以得出n=k,最大值为2^k+2^(k+1)+...+2^(2k+1)

 

代码如下

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		// min:2^(2n-1),max:2^n+...+2^(2n-1)
		int min = 1 << (2 * n - 1);// 2的2n-1次方
		int max = calEnd(n, 2 * n - 1);
		for (int j = min; j <= max; j++) {
			String binary = Integer.toBinaryString(j);
			char[] chs = binary.toCharArray();
			if (judge(chs)) {
				output(chs);
			}
		}
	}

	private static void output(char[] chs) {
		for (int i = 0; i < chs.length; i++) {
			if (chs[i] == '1') {
				System.out.print("T");
			} else {
				System.out.print("C");
			}
		}
		System.out.println();
	}

	private static boolean judge(char[] chs) {
		int flag = 0;
		for (int i = 0; i < chs.length; i++) {
			if (chs[i] == '1') {
				flag++;
			} else {
				flag--;
				if (flag < 0) {
					return false;
				}
			}
		}
		if (flag == 0) {
			return true;
		}
		return false;
	}

	private static int calEnd(int l, int r) {
		int sum = 0;
		for (int i = l; i <= r; i++) {
			sum += (1 << i);
		}
		return sum;
	}

}

 

你可能感兴趣的:(Java,笔试题,算法)