蓝桥杯2014真题练习

李白打酒
题目描述
  话说大诗人李白,一生好饮。幸好他从不开车。

    一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱:

    无事街上走,提壶去打酒。
    逢店加一倍,遇花喝一斗。

    这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。 

    请你计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b。则:babaabbabbabbbb 就是合理的次序。像这样的答案一共有多少呢?请你计算出所有可能方案的个数(包含题目给出的)。

    注意:通过浏览器提交答案。答案是个整数。不要书写任何多余的内容。
import java.util.Scanner;

/**
 * 李白打酒,深搜
 * 
 *
 */
public class Main {

	static int ans = 0;

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		dfs(5, 9, 2);
		System.out.println(ans);
	}

	public static void dfs(int i, int j, int k) {
		if (i == 0 && j == 0 && k == 1) {
			ans++;
		}
		// 遇到店
		if (i > 0)
			dfs(i - 1, j, k * 2);
		// 遇到花
		if (j > 0)
			dfs(i, j - 1, k - 1);
	}
}
神奇算式
题目描述
由4个不同的数字,组成的一个乘法算式,它们的乘积仍然由这4个数字组成。

    比如: 

210 x 6 = 1260 
8 x 473 = 3784
27 x 81 = 2187 

    都符合要求。

    如果满足乘法交换律的算式算作同一种情况,那么,包含上边已列出的3种情况,一共有多少种满足要求的算式。

    请填写该数字,通过浏览器提交答案,不要填写多余内容(例如:列出所有算式)。
import java.util.Arrays;

public class Main1 {

	static int ans = 0;

	public static void main(String[] args) {
		for (int i = 1; i < 10; i++) {
			for (int j = 0; j < 10; j++) {
				if (j != i) {
					for (int k = 0; k < 10; k++) {
						if (k != j && k != i) {
							for (int l = 0; l < 10; l++) {
								if (l != k && l != j && l != i) {
									int a1 = i * 1000 + j * 100 + k * 10 + l;
									// int a2=i*(j*100+k*10+l);
									// int a3=(i*10+j)*(k*10+l);
									// int a4=(i*100+j*10+k)*l;

									if (j != 0) {
										int a2 = i * (j * 100 + k * 10 + l);
										if (check(a1, a2)) {
											System.out.printf("%d*%d\n", i, j * 100 + k * 10 + l);
											ans++;
										}
									}
									if (k != 0) {
										int a3 = (i * 10 + j) * (k * 10 + l);
										if ((i * 10 + j) < (k * 10 + l) && check(a1, a3)) {
											System.out.printf("%d*%d\n", i, j * 100 + k * 10 + l);
											ans++;
										}
									}

								}
							}
						}
					}
				}
			}
		}
		System.out.println(ans);
	}

	// 判断两边4个不同数字,排序后相等
	public static boolean check(int a1, int an) {
		String s1 = Integer.toString(a1);
		String s2 = Integer.toString(an);
		char[] c1 = s1.toCharArray();
		char[] c2 = s2.toCharArray();
		Arrays.sort(c1);
		Arrays.sort(c2);
		return new String(c1).equals(new String(c2));
	}
}

六角填数
题目描述
 如图【1.png】所示六角形中,填入1~12的数字。

    使得每条直线上的数字之和都相同。

    图中,已经替你填好了3个数字,请你计算星号位置所代表的数字是多少?

请通过浏览器提交答案,不要填写多余的内容。

在这里插入图片描述

public class Main2 {

	static int[] a = { 2, 4, 5, 6, 7, 9, 10, 11, 12 };

	public static void main(String[] args) {
		dfs(0);
	}
	//全排列
	public static void dfs(int i) {
		if (i == a.length) {
			check();
			return;
		}
		for (int j = i; j < a.length; j++) {
			int t = a[i];
			a[i] = a[j];
			a[j] = t;
			dfs(i + 1);
			t = a[i];
			a[i] = a[j];
			a[j] = t;
		}

	}

	public static void check() {
		int r1 = 8 + a[0] + a[1] + a[2];
		int r2 = 1 + a[0] + a[3] + a[5];
		int r3 = 1 + a[1] + a[4] + a[8];
		int r4 = 11 + a[3] + a[6];
		int r5 = 3 + a[2] + a[4] + a[7];
		int r6 = a[5] + a[6] + a[7] + a[8];
		if (r1 == r2 && r2 == r3 && r3 == r4 && r4 == r5 && r5 == r6) {
			System.out.println(a[3]);
		}
	}
}

兰顿蚂蚁
题目描述
 兰顿蚂蚁,是于1986年,由克里斯·兰顿提出来的,属于细胞自动机的一种。

    平面上的正方形格子被填上黑色或白色。在其中一格正方形内有一只“蚂蚁”。
    蚂蚁的头部朝向为:上下左右其中一方。

    蚂蚁的移动规则十分简单:
    若蚂蚁在黑格,右转90度,将该格改为白格,并向前移一格;
    若蚂蚁在白格,左转90度,将该格改为黑格,并向前移一格。

    规则虽然简单,蚂蚁的行为却十分复杂。刚刚开始时留下的路线都会有接近对称,像是会重复,但不论起始状态如何,蚂蚁经过漫长的混乱活动后,会开辟出一条规则的“高速公路”。

    蚂蚁的路线是很难事先预测的。

    你的任务是根据初始状态,用计算机模拟兰顿蚂蚁在第n步行走后所处的位置。

【数据格式】

输入数据的第一行是 m n 两个整数(3 < m, n < 100),表示正方形格子的行数和列数。
接下来是 m 行数据。
每行数据为 n 个被空格分开的数字。0 表示白格,1 表示黑格。

接下来是一行数据:x y s k, 其中x y为整数,表示蚂蚁所在行号和列号(行号从上到下增长,列号从左到右增长,都是从0开始编号)。s 是一个大写字母,表示蚂蚁头的朝向,我们约定:上下左右分别用:UDLR表示。k 表示蚂蚁走的步数。

输出数据为两个空格分开的整数 p q, 分别表示蚂蚁在k步后,所处格子的行号和列号。


例如, 输入:
5 6
0 0 0 0 0 0
0 0 0 0 0 0
0 0 1 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
2 3 L 5
程序应该输出:
1 3

再例如, 输入:
3 3
0 0 0
1 1 1
1 1 1
1 1 U 6
程序应该输出:
0 0


资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗  < 1000ms


请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。

在这里插入图片描述

import java.util.Scanner;

public class Main3 {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int m = sc.nextInt();
		int n = sc.nextInt();
		int[][] a = new int[m][n];
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < n; j++) {
				a[i][j] = sc.nextInt();
			}
		}

		int x = sc.nextInt();
		int y = sc.nextInt();
		String s = sc.next();
		int k = sc.nextInt();

		int d = getD(s);
		int step = 0;
		while (true) {

			// 蚂蚁在黑格
			if (a[x][y] == 1) {
				d = d % 4 + 1;
				a[x][y] = 0;

			}
			// 蚂蚁在白格
			else {
				d = d - 1;
				if (d == 0)
					d = 4;
				a[x][y] = 1;

			}
			if (d == 1)
				x--;
			if (d == 2)
				y++;
			if (d == 3)
				x++;
			if (d == 4)
				y--;
			step++;
			if (step == k) {
				System.out.println(x + " " + y);
				break;
			}
		}
	}

	public static int getD(String s) {
		if (s.equals("U"))
			return 1;
		if (s.equals("R"))
			return 2;
		if (s.equals("D"))
			return 3;
		if (s.equals("L"))
			return 4;

		return 0;
	}
}

波动数列
题目描述
 观察这个数列:
    1 3 0 2 -1 1 -2 ...

这个数列中后一项总是比前一项增加2或者减少3。

栋栋对这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加a或者减少b的整数数列可能有多少种呢?

【数据格式】
    输入的第一行包含四个整数 n s a b,含义如前面说述。
    输出一行,包含一个整数,表示满足条件的方案数。由于这个数很大,请输出方案数除以100000007的余数。

例如,输入:
4 10 2 3
程序应该输出:
2

【样例说明】
这两个数列分别是2 4 1 3和7 4 1 -2。

【数据规模与约定】
对于10%的数据,1<=n<=5,0<=s<=5,1<=a,b<=5;
对于30%的数据,1<=n<=30,0<=s<=30,1<=a,b<=30;
对于50%的数据,1<=n<=50,0<=s<=50,1<=a,b<=50;
对于70%的数据,1<=n<=100,0<=s<=500,1<=a, b<=50;
对于100%的数据,1<=n<=1000,-1,000,000,000<=s<=1,000,000,000,1<=a, b<=1,000,000。

资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗  < 2000ms


请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
import java.util.Scanner;

/**
 * 思路:假设第一项为x,P={a,-b},n项和可以等价于 x+x+P+x+2P...x+(n-1)P=s,相当于(s-(n*(n-1)/2)*P)/n=x
 * 假设a的系数为i,-b的系数为j,则(n*(n-1)/2)*P=ia-jb i+j=n*(n-1)/2,所以(s-ia+jb)/n=x
 * x为正整数,所以需要满足(s-ia+jb)%n==0 i和j的选择有很多种,假如i=6,则i可以有1,5组成或者2,4组成,
 * a前面的系数选择范围为0~n-1 所以相当于用0~n-1组合出i,知道i就可以知道j, dp[j]是用0~n-1组合0~n-1的方案数
 * 转化为0-1背包问题
 */
public class Main5 {
	static int n;
	static long s;
	static long a;
	static long b;

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		s = sc.nextLong();
		a = sc.nextLong();
		b = sc.nextLong();

		int t = n * (n - 1) / 2;
		int[] dp = new int[t + 1];
		dp[0] = 1;
		for (int i = 1; i <= n - 1; i++) {
			// 根据i和j的关系得到通过上面的i最多组成j的值
			for (int j = i * (i + 1) / 2; j >= i; j--) {
				// 选择i和不选择i的和
				dp[j] = (dp[j] + dp[j - i]) % 100000007;
			}
		}
		long ans = 0;
		for (int i = 0; i <= t; i++) {
			if ((s - i * a + (t - i) * b) % n == 0)
				ans = (ans + dp[i]) % 100000007;
		}
		System.out.println(ans);
	}

}

标题:六角幻方

把 1 2 3 ... 19 共19个整数排列成六角形状,如下:

    * * *
   * * * *
  * * * * *
   * * * * 
    * * *

要求每个直线上的数字之和必须相等。共有15条直线哦!

再给点线索吧!我们预先填好了2个数字,第一行的头两个数字是:15 13,参见图【p1.png】,黄色一行为所求。

请你填写出中间一行的5个数字。数字间用空格分开。

这是一行用空格分开的整数,请通过浏览器提交答案,不要填写任何多余的内容(比如说明性的文字等)

在这里插入图片描述

/**
 * 
 * 思路,全排列,在每一个特殊点进行判断剪枝
 *
 */
public class Main7 {

	static int[] a = { 15, 13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 17, 18, 19 };

	public static void main(String[] args) {
		dfs(2);

	}

	public static void dfs(int i) {
		// 有两条线可以判断
		if (i == 7) {
			if (a[0] + a[1] + a[2] != a[3] + a[4] + a[5] + a[6])
				return;
		}

		// 有三条线可以判断
		if (i == 12) {
			if (a[0] + a[1] + a[2] != a[0] + a[3] + a[7])
				return;
			if (a[0] + a[1] + a[2] != a[7] + a[8] + a[9] + a[10] + a[11])
				return;
			if (a[0] + a[1] + a[2] != a[2] + a[6] + a[11])
				return;
		}

		// 有三条线可以判断
		if (i == 16) {
			if (a[0] + a[1] + a[2] != a[1] + a[4] + a[8] + a[12])
				return;
			if (a[0] + a[1] + a[2] != a[12] + a[13] + a[14] + a[15])
				return;
			if (a[0] + a[1] + a[2] != a[1] + a[5] + a[10] + a[15])
				return;
		}

		// 有五条线可以判断
		if (i == 19) {
			if (a[0] + a[1] + a[2] != a[7] + a[12] + a[16])
				return;
			if (a[0] + a[1] + a[2] != a[3] + a[8] + a[13] + a[17])
				return;
			if (a[0] + a[1] + a[2] != a[0] + a[4] + a[9] + a[14] + a[18])
				return;
			if (a[0] + a[1] + a[2] != a[2] + a[5] + a[9] + a[13] + a[16])
				return;
			if (a[0] + a[1] + a[2] != a[6] + a[10] + a[14] + a[17])
				return;
			if (a[0] + a[1] + a[2] != a[11] + a[15] + a[18])
				return;
			if (a[0] + a[1] + a[2] != a[16] + a[17] + a[18])
				return;
		}
		if (i >= 19) {
			for (int k = 7; k < 12; k++) {
				System.out.println(a[k] + " ");
			}
			return;
		}

		// 全排列
		for (int j = i; j < a.length; j++) {
			int t = a[j];
			a[j] = a[i];
			a[i] = t;
			dfs(i + 1);
			t = a[j];
			a[j] = a[i];
			a[i] = t;
		}

	}
}

猜字母
题目描述

把abcd…s共19个字母组成的序列重复拼接106次,得到长度为2014的串。

接下来删除第1个字母(即开头的字母a),以及第3个,第5个等所有奇数位置的字母。

得到的新串再进行删除奇数位置字母的动作。如此下去,最后只剩下一个字母,请写出该字母。

答案是一个小写字母,请通过浏览器提交答案。不要填写任何多余的内容。
public class Main8 {

	public static void main(String[] args) {
		char[] str = new char[2014];
		int index = 0;
		for (int i = 0; i < 106; i++) {
			for (int j = 0; j < 19; j++) {
				str[index++] = (char) ('a' + j);
			}
		}

		int len = 2014;
		while (len != 1) {
			int k = 0;
			for (int i = 1; i < len; i += 2) {
				str[k++] = str[i];
			}
			len = k;
		}

		System.out.println(str[0]);
	}
}

奇怪的分式
题目描述:

上小学的时候,小明经常自己发明新算法。一次,老师出的题目是:
1/4 乘以 8/5

小明居然把分子拼接在一起,分母拼接在一起,答案是:18/45 (参见图1.png)

老师刚想批评他,转念一想,这个答案凑巧也对啊,真是见鬼!

对于分子、分母都是 1~9 中的一位数的情况,还有哪些算式可以这样计算呢?

请写出所有不同算式的个数(包括题中举例的)。

显然,交换分子分母后,例如:4/1 乘以 5/8 是满足要求的,这算做不同的算式。

但对于分子分母相同的情况,2/2 乘以 3/3 这样的类型太多了,不在计数之列!

注意:答案是个整数(考虑对称性,肯定是偶数)。请通过浏览器提交。不要书写多余的内容。

/**
 * 
 * 考察gcd
 *
 */
public class Main9 {

	// 最大公约数
	public static int gcd(int i, int j) {
		if (j == 0)
			return i;
		return gcd(j, i % j);
	}

	public static void main(String[] args) {
		int ans = 0;
		for (int a = 1; a < 10; a++) {
			for (int b = 1; b < 10; b++) {
				if (b == a)
					continue;
				for (int c = 1; c < 10; c++) {
					for (int d = 1; d < 10; d++) {
						if (d == c)
							continue;
						int g1 = gcd(a * c, b * d);
						int g2 = gcd(a * 10 + c, b * 10 + d);
						if (a * c / g1 == (a * 10 + c) / g2 && b * d / g1 == (b * 10 + d) / g2) {
							ans++;
						}
					}
				}
			}
		}
		System.out.println(ans);
	}

}

地宫取宝
题目描述

X 国王有一个地宫宝库。是 n x m 个格子的矩阵。每个格子放一件宝贝。每个宝贝贴着价值标签。
地宫的入口在左上角,出口在右下角。

小明被带到地宫的入口,国王要求他只能向右或向下行走。

走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。

当小明走到出口时,如果他手中的宝贝恰好是k件,则这些宝贝就可以送给小明。

请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这k件宝贝。

【数据格式】

输入一行3个整数,用空格分开:n m k (1<=n,m<=50, 1<=k<=12)

接下来有 n 行数据,每行有 m 个整数 Ci (0<=Ci<=12)代表这个格子上的宝物的价值

要求输出一个整数,表示正好取k个宝贝的行动方案数。该数字可能很大,输出它对 1000000007 取模的结果。

例如,输入:
2 2 2
1 2
2 1
程序应该输出:
2

再例如,输入:
2 3 2
1 2 3
2 1 5
程序应该输出:
14

资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 2000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
import java.util.Scanner;

public class Main10 {

	static long MOD = 1000000007;
	static int n, m, k;
	static int[][] a;
	static int[][][][] dp = new int[50][50][15][15];

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		m = sc.nextInt();
		k = sc.nextInt();
		a = new int[n][m];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				a[i][j] = sc.nextInt();
			}
		}

		for (int i = 0; i < 50; i++) {
			for (int j = 0; j < 50; j++) {
				for (int k = 0; k < 15; k++) {
					for (int l = 0; l < 15; l++) {
						dp[i][j][k][l] = -1;
					}
				}
			}
		}

		int res = dfs(0, 0, 0, -1);
		System.out.println(res);
	}

	/**
	 * 位置
	 * 
	 * @param x
	 * @param y
	 *            数量
	 * @param num
	 *            最大价值
	 * @param max
	 * @return
	 */
	public static int dfs(int x, int y, int num, int max) {

		// 记忆化搜索
		if (dp[x][y][num][max + 1] != -1) {
			return dp[x][y][num][max + 1];
		}

		if (x == n - 1 && y == m - 1) {
			if (num == k || (num == k - 1 && max < a[x][y]))
				return dp[x][y][num][a[x][y]] = 1;
			else
				return dp[x][y][num][a[x][y]] = 0;
		}

		long ans = 0;
		if (x < n - 1) {
			// 拿当前位置的物品
			if (max < a[x][y]) {
				ans += dfs(x + 1, y, num + 1, a[x][y]);
			}
			// 不拿
			ans += dfs(x + 1, y, num, max);
			ans %= MOD;
		}

		if (y < m - 1) {
			if (max < a[x][y]) {
				ans += dfs(x, y + 1, num + 1, a[x][y]);
			}
			ans += dfs(x, y + 1, num, max);
			ans %= MOD;
		}

		return dp[x][y][num][max + 1] = (int) ans;
	}
}

矩阵翻硬币

问题描述

小明先把硬币摆成了一个 n 行 m 列的矩阵。随后,小明对每一个硬币分别进行一次 Q 操作。对第x行第y列的硬币进行 Q 操作的定义:将所有第 i*x 行,第 j*y 列的硬币进行翻转。其中i和j为任意使操作可行的正整数,行号和列号都是从1开始。当小明对所有硬币都进行了一次 Q 操作后,他发现了一个奇迹——所有硬币均为正面朝上。小明想知道最开始有多少枚硬币是反面朝上的。于是,他向他的好朋友小M寻求帮助。

聪明的小M告诉小明,只需要对所有硬币再进行一次Q操作,即可恢复到最开始的状态。然而小明很懒,不愿意照做。于是小明希望你给出他更好的方法。帮他计算出答案。

输入格式
  输入数据包含一行,两个正整数 n m,含义见题目描述。
输出格式
  输出一个正整数,表示最开始有多少枚硬币是反面朝上的。
样例输入
2 3
样例输出
1
数据规模和约定
  对于10%的数据,n、m <= 10^3;
  对于20%的数据,n、m <= 10^7;
  对于40%的数据,n、m <= 10^15;
  对于10%的数据,n、m <= 10^1000(10的1000次方)
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Scanner;

/**
 * 如果一个硬币反转了n次后正面朝上,且初 始状态为反面朝上,那么n一定是个奇数。 根据题意“ 对第x行第y列的硬币进行 Q 操作的 定义:将所有第 i*x
 * 行,第 j*y 列的硬币进行 翻转”。我们逆向的理解这个意思,对与一个横坐标为x的 硬币而言,我们反转那些硬币时会需要翻转它呢?答案是横坐标的x的约数。
 * 例如x=9时,翻转横坐标为1,3,9的时候会影响它的翻转,纵坐标同理。
 * 
 * 那么这个题目我们就可以通过求解拥有奇数个 约数的数来实现,在数学上这种数字又叫做完全平 方数。即1,4,9,16,25......(2^n)
 * 
 * 我们知道矩阵的行号和列号是从1开始的 ,横坐标1-n,纵坐标1-m,那么我们需要解决的及时 其间的完全平方数的个数问题,最后相乘即可得到
 * (相乘是因为横坐标的翻转会影响纵坐标,纵坐标的翻转也会影响横坐标)。 这里需要用到大数开方 如果一个数的位数n为偶数,那么这个数开方之后就有n/2位;
 * 如果一个数的位数为奇数,那么这个数开方之后就有n/2+1位;
 *
 */
public class Main11 {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String n = sc.next();
		String m = sc.next();
		System.out.println(sqrt(n).multiply(sqrt(m)));
	}

	public static BigInteger sqrt(String num) {
		int len = num.length();
		if (len % 2 == 0)
			len /= 2;
		else
			len = len / 2 + 1;
		char[] cc = new char[len];
		Arrays.fill(cc, '0');
		// 枚举位置上的数字
		for (int pos = 0; pos < len; pos++) {
			for (char i = '1'; i <= '9'; i++) {
				cc[pos] = i;
				String ccs = String.valueOf(cc);
				BigInteger a = new BigInteger(num);
				BigInteger b = new BigInteger(ccs).pow(2);
				if (b.compareTo(a) == 1) {
					cc[pos] -= 1;
					break;
				}
			}
		}
		return new BigInteger(String.valueOf(cc));
	}
}

分糖果
题目描述:

有n个小朋友围坐成一圈。老师给每个小朋友随机发偶数个糖果,然后进行下面的游戏:
每个小朋友都把自己的糖果分一半给左手边的孩子。

一轮分糖后,拥有奇数颗糖的孩子由老师补给1个糖果,从而变成偶数。

反复进行这个游戏,直到所有小朋友的糖果数都相同为止。

你的任务是预测在已知的初始糖果情形下,老师一共需要补发多少个糖果。

【格式要求】

程序首先读入一个整数N(2<N<100),表示小朋友的人数。
接着是一行用空格分开的N个偶数(每个偶数不大于1000,不小于2)
要求程序输出一个整数,表示老师需要补发的糖果数。

例如:输入
3
2 2 4
程序应该输出:
4

资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
import java.util.Scanner;

public class Main12 {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt();
		int[] a = new int[N];
		for (int i = 0; i < N; i++) {
			a[i] = sc.nextInt();
		}
		int sum = 0;
		int[] b = new int[N];
		while (true) {
			for (int i = 0; i < a.length; i++) {
				b[i] = a[i] / 2;
			}
			for (int i = a.length - 1; i >= 0; i--) {
				a[i] = a[i] / 2 + b[(i + 1) % N];
			}
			if (check(a)) {
				break;
			}
			for (int i = 0; i < a.length; i++) {
				if (a[i] % 2 != 0) {
					a[i] += 1;
					sum += 1;
				}
			}
			if (check(a)) {
				break;
			}
		}
		System.out.println(sum);
	}

	public static boolean check(int[] a) {
		for (int i = 1; i < a.length; i++) {
			if (a[0] != a[i])
				return false;
		}
		return true;
	}
}

扑克序列
题目描述:
A A 2 2 3 3 4 4, 一共4对扑克牌。请你把它们排成一行。
要求:两个A中间有1张牌,两个2之间有2张牌,两个3之间有3张牌,两个4之间有4张牌。

请填写出所有符合要求的排列中,字典序最小的那个。

例如:22AA3344 比 A2A23344 字典序小。当然,它们都不是满足要求的答案。

请通过浏览器提交答案。“A”一定不要用小写字母a,也不要用“1”代替。字符间一定不要留空格。
思路:全排列后排序,对A做了预处理,替换成1

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Main13 {

	static char[] c= {'1','1','2','2','3','3','4','4'};
	static Set<String> set=new HashSet<>();
	public static void main(String[] args) {
		dfs(0);
		List<String> list=new ArrayList(set);
		Collections.sort(list);
		System.out.println(list.get(0).replace('1', 'A'));
	}
	public static void dfs(int i) {
		if(i==c.length) {
			check();
			return;
		}
		for(int j=i;j<c.length;j++) {
			char t=c[i];
			c[i]=c[j];
			c[j]=t;
			dfs(i+1);
			t=c[i];
			c[i]=c[j];
			c[j]=t;
		}
		
	}
	public static void check() {
		String s=String.valueOf(c);
		//System.out.println(s);
		boolean flag=true;
		if(s.indexOf("1")+2!=s.lastIndexOf("1"))
			flag=false;
		if(s.indexOf("2")+3!=s.lastIndexOf("2"))
			flag=false;
		if(s.indexOf("3")+4!=s.lastIndexOf("3"))
			flag=false;
		if(s.indexOf("4")+5!=s.lastIndexOf("4"))
			flag=false;
		if(flag) {
			//System.out.println(s);
			set.add(s);
		}
		
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值