蓝桥杯2016Java_A组

蓝桥杯2016Java_A组

1. 煤球数目

/*
煤球数目

有一堆煤球,堆成三角棱锥形。具体:
第一层放1个,
第二层3个(排列成三角形),
第三层6个(排列成三角形),
第四层10个(排列成三角形),
....
如果一共有100层,共有多少个煤球?

请填表示煤球总数目的数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
*/
//每一次都比上一层多一个球,2,3,4,5.....
//答案:171700
public class _01煤球数目 {

	public static void main(String[] args) {
		int pre = 1;
		int plus = 2;
		long sum = 1;
		for(int k = 2 ;k <= 100 ; k++){ //从第二层开始
			pre = pre + plus;
			sum += pre;
			plus++;//一层增一个
		}
		System.out.println(sum);
	}

}

2.生日蜡烛

/*
生日蜡烛

某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛。

现在算起来,他一共吹熄了236根蜡烛。

请问,他从多少岁开始过生日party的?

请填写他开始过生日party的年龄数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

答案:26

*/
public class _02生日蜡烛 {

	public static void main(String[] args) {
//		f1(); 方法1
//		f2(); 方法2 
		f3(); //方法3
	}
	
	//暴力
	static void f3(){
		for(int i = 1;  i< 100 ; i++){
			int sum = i; //每一次从 i 岁开始
			for(int j = 1 ; j <= i ; j++){
				sum += j; 
				if(sum==236)
				{
					System.out.println(i);
					break;
				}
			}
		}
	}
	static void f2(){
		for(int i = 1 ; i< 100 ;i++){
			for(int j = i ; j < 100 ; j++){
				if((i+j)*(j-i+1)/2 == 236){
					System.out.print(i);
				}
			}
		}
	}
	
	static void f1(){
		for(int i = 1 ; i< 100 ; i++){
			int t = i*(i-1)/2;
			if((236-t)%i == 0){
				//输出首项
				System.out.println((236-t)/i+" "+i);
			}
		}
	}

}

3. 搭积木

/*
 搭积木

 小明最近喜欢搭数字积木,
 一共有10块积木,每个积木上有一个数字,0~9。

 搭积木规则:
 每个积木放到其它两个积木的上面,并且一定比下面的两个积木数字小。
 最后搭成4层的金字塔形,必须用完所有的积木。

 下面是两种合格的搭法:

 0
 1 2
 3 4 5
 6 7 8 9

 0
 3 1
 7 5 2
 9 8 6 4

 请你计算这样的搭法一共有多少种?

 请填表示总数目的数字。
 注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

 */
//这是判断的条件
//每个积木放到其它   两个积木   的上面,并且一定比   下面    的    两个   积木数字    小。
//答案:768
public class _03搭积木 {

	static int[] arr = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	private static int ans;

	public static void main(String[] args) {
		f(0);
		System.out.println(ans);
	}

/*
   0
  1 2
 3 4 5
6 7 8 9
 */
	// 全排列
	private static void f(int k) {
	    if (k == 10) {
	      ans++;
	    }
	    for (int i = k; i < 10; i++) {
	      swap(k, i);
	    //每个积木放到其它   两个积木   的上面,并且一定比   下面    的    两个   积木数字    小。
	      //剪枝
	      if (k==1&&arr[1]<arr[0]||
	          k==2&&arr[2]<arr[0]||
	          k==3&&arr[3]<arr[1]||
	          k==4&&(arr[4]<arr[1]||arr[4]<arr[2])||
	          k==5&&arr[5]<arr[2]||
	          k==6&&arr[6]<arr[3]||
	          k==7&&(arr[7]<arr[3]||arr[7]<arr[4])||
	          k==8&&(arr[8]<arr[4]||arr[8]<arr[5])||
	          k==9&&arr[9]<arr[5])
	      {
	        swap(k, i);
	        continue;//跳过
	      }
	      f(k + 1);
	      swap(k, i);
	    }
	  }
	// 交换
	private static void swap(int k, int i) {
		int t = arr[i];
		arr[i] = arr[k];
		arr[k] = t;
	}
}

6. 寒假作业

/*
 寒假作业

 现在小学的数学题目也不是那么好玩的。
 看看这个寒假作业:

 □ + □ = □
 □ - □ = □
 □ × □ = □
 □ ÷ □ = □

 (如果显示不出来,可以参见【图1.jpg】)

 每个方块代表1~13中的某一个数字,但不能重复。
 比如:
 6  + 7 = 13
 9  - 8 = 1
 3  * 4 = 12
 10 / 2 = 5

 以及:
 7  + 6 = 13
 9  - 8 = 1
 3  * 4 = 12
 10 / 2 = 5

 就算两种解法。(加法,乘法交换律后算不同的方案)

 你一共找到了多少种方案?


 请填写表示方案数目的整数。
 注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

 */
//答案:64
public class _06寒假作业 {

	static int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
	static int ans;

	public static void main(String[] args) {
		f(0);
		System.out.println(ans);
	}

	static void f(int k) {

		if (k == 13) {
			if (check()) {
				ans++;
			}
		}
		for (int i = k; i < 13; i++) {
			swap(i, k);
			
			//提前排除,提升效率,剪枝
			//一定要用 k等于 那个数 , 不然会出错
			if(k == 2 && a[0]+a[1]!=a[2] || k == 5 && a[3]-a[4]!=a[5]){
				swap(i, k); //交换回来,如不换回来也会出错
				continue;
			}
			f(k + 1);
			swap(i, k);
		}
	}

	static boolean check() {
		//有13个数没有用完,因为换来换去最后还是会换到的
		if (	a[0] + a[1] == a[2] &&
				a[3] - a[4] == a[5] && 
				a[6] * a[7] == a[8] && 
				a[9] % a[10] == 0 	&&
				a[9] / a[10] == a[11]) {
			return true;
		}
		return false;
	}

	// 交换
	static void swap(int i, int k) {
		int t = a[i];
		a[i] = a[k];
		a[k] = t;
	}

}

7. 剪邮票

/*
 剪邮票

 如【图1.jpg】, 有12张连在一起的12生肖的邮票。
 现在你要从中剪下5张来,要求必须是连着的。
 (仅仅连接一个角不算相连)
 比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。

 请你计算,一共有多少种不同的剪取方法。

 请填写表示方案数目的整数。
 注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
 */
//答案:116

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

public class _07剪邮票 {

	static int ans;
	//剪下5张,所以有5个1
	static int a[] = { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 };

	// 它的每个排列代表着12选5的一个方案
	public static void main(String[] args) {
		int[] path = new int[12];
		f(0, path);
		System.out.println(ans);
	}

	static boolean vis[] = new boolean[12];//默认为false

	static void f(int k, int path[]) {

		if (k == 12) {
			if (check(path)) {
				ans++;
			}
		}
		
		for (int i = 0; i < 12; i++) {

			if (i > 0 && a[i] == a[i - 1] && !vis[i - 1])
				continue;
			// 现在准备选取的元素和上一个元素相同,但是上一个元素还没使用
			if (!vis[i]) { // 没有被用过的元素可以抓入到path
				vis[i] = true; // 标记为已访问
				path[k] = a[i]; // 将a[i]填入到path[k]中
				f(k + 1, path); // 递归
				vis[i] = false;// 回溯
			}
		}
	}

	static boolean check(int path[]) {
		int g[][] = new int[3][4];
		// 将某个排列映射到二维矩阵上
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 4; j++) {
				if (path[i * 4 + j] == 1) { //每行每列的个个数 true == 1
					g[i][j] = 1;
				} else {
					g[i][j] = 0;
				}
			}
		}
		int cnt = 0; // 连通块的数目

		// 上面就有5个格子被标记为1,现在才用dfs做连通性检查,要求只有一个连通块
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 4; j++) {
				if (g[i][j] == 1) {
					dfs(g, i, j);
					cnt++;
				}
			}
		}
		return cnt == 1; //说明为连通
	}

	static void dfs(int g[][], int i, int j) {
		g[i][j] = 0;
		if (i - 1 >= 0 && g[i - 1][j] == 1)
			dfs(g, i - 1, j); //上
		
		if (i + 1 <= 2 && g[i + 1][j] == 1)
			dfs(g, i + 1, j); //下
		
		if (j - 1 >= 0 && g[i][j - 1] == 1)
			dfs(g, i, j - 1); //左
		
		if (j + 1 <= 3 && g[i][j + 1] == 1)
			dfs(g, i, j + 1); //右
	}

}

8.交换瓶子

/*
交换瓶子

有N个瓶子,编号 1 ~ N,放在架子上。

比如有5个瓶子:
2 1 3 5 4

要求每次拿起2个瓶子,交换它们的位置。
经过若干次后,使得瓶子的序号为:
1 2 3 4 5

对于这么简单的情况,显然,至少需要交换2次就可以复位。

如果瓶子更多呢?你可以通过编程来解决。

输入格式为两行:
第一行: 一个正整数N(N<10000), 表示瓶子的数目
第二行:N个正整数,用空格分开,表示瓶子目前的排列情况。

输出数据为一行一个正整数,表示至少交换多少次,才能完成排序。

例如,输入:
5
3 1 2 5 4

程序应该输出:
3

再例如,输入:
5
5 4 3 2 1

程序应该输出:
2

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


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

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


*/
public class _08交换瓶子 {

	static int n;
	static int[] a = new int[10001];
	static int ans;
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		//处理输入
		n = sc.nextInt();
		for(int i = 1 ; i <= n ;i++){
			a[i] = sc.nextInt();
		}
		
		//遍历i : i - N
		for(int i = 1 ; i <= n ; i++){
			//如果a[i] = i , 已经到位
			if(a[i] == i) //就是当前位置对,不用交换
				continue;
			//否则先找到i在a中的位置pos(i)和i位交换 -- swap(a , pos(i),i)
			else{
				swap(pos(i) , i); //返回下标后就和当前的下标交换
				ans++;
			}
		}
		System.out.println(ans);
	}
	
	static int pos(int x){
		for(int i = 1 ; i <= n ;i++){ 
			if(a[i] == x) //遍历数组找到 当前数的下标 返回
				return i;
		}
		return -1;
	}
	//交换
	static void swap(int i , int j){
		int t = a[i];
		a[i] = a[j];
		a[j] = t;
	}
	

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值