蓝桥杯省赛夺奖冲刺营枚举法

本文介绍了如何使用枚举法解决蓝桥杯竞赛中的数学问题,包括简单型枚举、组合型枚举、排列型枚举和指数型枚举。通过示例代码详细阐述了各种枚举策略,并提供了实际问题的解决方案,如24点游戏、公平抽签和座次问题。这些方法对于解决实际编程挑战具有指导意义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

蓝桥杯省赛夺奖冲刺营枚举法

简单型枚举

「42 点问题」

题目描述
请你设计一个程序对该问题进行解答。

众所周知在扑克牌中,有一个老掉牙的游戏叫做 24 点,选取 4 张牌进行加减乘除,看是否能得出 24 这个答案。

现在小蓝同学发明了一个新游戏,他从扑克牌中依次抽出6张牌,注意不是一次抽出,进行计算,看是否能够组成 42 点,满足输出 YES,反之输出 NO。

最先抽出来的牌作为第一个操作数,抽出牌做第二个操作数,运算结果再当作第一个操作数,继续进行操作。

注:除不尽的情况保留整数,而且扑克牌的四张 1010 都丢了,不会出现 10。

请设计一个程序对该问题进行解答。

输入描述
输出仅一行包含 6 个字符。

保证字符 ∈ 3 4 5 6 7 8 9 10 J Q K A 2。

输出描述
若给出到字符能够组成 4242 点 , 满足输出 YES,反之输出 NO。

输入输出样例
示例
输入

K A Q 6 2 3 

输出

YES

样例说明
K×A=K 即 13×1=13
13/12=1保留整数
1+6=7
7∗2=14
14∗3=42

运行限制
最大运行时间:1s
最大运行内存: 128M

备注:

相当于有一个大数组,大数组里面有6个小数组
第一个小数组里只有num[0]
第二个小数组里有num[0]分别加减乘除num[1]后的4个结果
第三个小数组里有第二个小数组里的4个数分别对num[2]进行加减乘除后的结果,也就是4个数*4个运算=16个结果
...
以此类推
最后遍历最后一个,也就是第六个小数组,里面如果有42就YES,没有就NO

代码

import java.util.Scanner;
import java.util.Vector;

public class Main {
	static Vector<Vector<Integer>> ans=new Vector<Vector<Integer>>();
	static int[] num=new int[6];
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		for (int i = 0; i < 6; i++) {
			String s=sc.next();
			if(Character.isDigit(s.charAt(0))) {
				num[i]=s.charAt(0)-'0';
			}else {
				if(s.equals("J")) {
					num[i]=11;
				}else if(s.equals("Q")) {
					num[i]=12;
				}else if(s.equals("K")) {
					num[i]=13;
				}else if(s.equals("A")) {
					num[i]=1;
				}
			}
		}
		ans.add(new Vector<>());
		ans.get(0).add(num[0]);
		for (int i = 0; i < 5; i++) {
			ans.add(new Vector<>());
			for (int j = 0; j < ans.get(i).size(); j++) {
				int t=ans.get(i).get(j);
				ans.get(i+1).add(t+num[i+1]);
				ans.get(i+1).add(t-num[i+1]);
				ans.get(i+1).add(t*num[i+1]);
				ans.get(i+1).add(t/num[i+1]);
			}
		}
		boolean flag=false;
		for (int i = 0; i < ans.get(5).size(); i++) {
			if(ans.get(5).get(i)==42) {
				flag=true;
				break;
			}
		}
		if(flag) {
			System.out.println("YES");
		}else {
			System.out.println("NO");
		}
	}
}

组合型枚举

组合型模板


注意:
1.chosen.remove((Object)x);
	vector的remove有两种,一种是传入index,一种是传入要删除的东西;这里的东西刚好是int类型,就会被理解为是index,就会出错,所以一定要加(Object)
2.这段代码,两种写法都可以
	2.1:这种写法,输出的答案特点是:1 2 ;1 3;2 3 
		   calc(x + 1);
		   chosen.addElement(x);
		   calc(x + 1);
		   chosen.remove((Object)x);
	2.2:这种写法,输出的答案特点是:2 3;1 3;1 2  
	       chosen.addElement(x);
	       calc(x + 1);
	       chosen.remove((Object)x);
	       calc(x + 1);
public class Main {

  static  int n;
  static int m;//选m个数
  static Vector<Integer> chosen = new Vector<Integer>();
  static <object> void calc(int x) {

      if (chosen.size() > m || chosen.size() + (n - x + 1) < m) //剪枝
          return;
      if (x == n + 1) { //选够了m个数输出
          String ansTem = "";

          for (int i = 0; i < chosen.size(); i++)
              System.out.print(chosen.get(i)+" ");

          System.out.println("");
          return;
      }
      calc(x + 1);
      chosen.addElement(x);
      calc(x + 1);
      chosen.remove((Object)x);//注意
  }
  public static void main(String[] args) {
      Scanner in = new Scanner(System.in);
      n = in.nextInt();
      m = in.nextInt();
      calc(1);
  }
}

「公平抽签」

题目描述

小A的学校,蓝桥杯的参赛名额非常有限,只有 m 个名额,但是共有 n 个人报名。

作为老师非常苦恼,他不知道该让谁去,他在寻求一个绝对公平的方式。

于是他准备让大家抽签决定,即 m 个签是去,剩下的是不去。

小A非常想弄明白最后的抽签结果会有多少种不同到情况,请你设计一个程序帮帮小A!

输入描述
输入第一行包含两个字符n,m,其含义如题所述。

接下来第二行到第 n+1 行每行包含一个字符串 S ,表示个人名。

1≤m≤n≤15。

输出描述
输出共若干行,每行包含 m 个字符串,表示该结果被选中到人名。

输入输出样例
示例
输入

3 2
xiaowang
xiaoA
xiaoli

输出

xiaowang xiaoA
xiaowang xiaoli
xiaoA xiaoli

运行限制
最大运行时间:1s
最大运行内存: 128M

代码

import java.util.Scanner;
import java.util.Vector;

public class Main {
	static int n;
	static int m;
	static Vector<Integer> chosen=new Vector<Integer>();
	static Vector<String> name=new Vector<String>();
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		n=sc.nextInt();
		m=sc.nextInt();
		for (int i= 0; i < n; i++) {
			name.add(sc.next());
		}
		calc(1);
	}
	private static void calc(int i) {
		if(chosen.size()>m||chosen.size()+(n-i+1)<m)return;
		if(i==n+1) {
			for (Integer x : chosen) {
				System.out.print(name.get(x-1)+" ");
			}
			System.out.println();
		}
		chosen.add(i);
		calc(i+1);
		chosen.remove((Object)i);
		calc(i+1);
	}
}

排列型枚举

全排列模板1

  static  int n;
  static int[] order =new int[20];
  static boolean[] chosen =new boolean[20];
  static <object> void calc(int x) {
      if (x == n + 1) { //选够了m个数输出
          String ansTem = "";
          for (int i = 1; i <=n ; i++)
              System.out.println(order[i]);
          return;
      }
      for (int i = 1; i <= n; i++) {
          if (chosen[i]) continue;
          order[x] = i;
          chosen[i] =true;
          calc(x + 1);
          chosen[i] = false;
          order[x] = 0;
      }
  }
  public static void main(String[] args) {
      Scanner in = new Scanner(System.in);
      n = in.nextInt();
      for (int i = 0; i < n; i++) {
         String s;
          s=in.next();
          name.addElement(s);
      }
      calc(1);
  }

全排列模板2

这个好记点

public class A09_全排列 { //——整数数组
	// 数字型、字符串、含重复元素的全排列 子集的生成、真子集、集合
	public static void main(String[] args) {
		int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
		f(arr1, 0);
	}
 
	// 确认某一个排列的第k位
	private static void f(int[] arr, int k) {
		if (k == arr.length) { // 全部确认
			for (int x : arr) {
				System.out.print(x);
			}
			System.out.println();
			return;
		}
		for (int i = k; i < arr.length; i++) { // 选定第k位,
			// 将第i位和第k位交换
			int t = arr[i];arr[i] = arr[k];arr[k] = t;
			f(arr, k + 1); // 移交下一层去确认k+1位
			// 回溯(换回来)
			t = arr[i];arr[i] = arr[k];arr[k] = t;
		}
	}
 
}

「座次问题」

题目描述
小A 的学校,老师好不容易解决了蓝桥杯的报名问题,现在老师又犯愁了。

现在有 N 位同学参加比赛,但是老师想给他们排座位,但是排列方式太多了。

老师非常想弄明白最后的排座次的结果是什么样子的,到底有多少种结果。

请设计一个程序帮助老师。

最后输出各种情况的人名即可,一行一种情况,每种情况的名字按照报名即输入顺序排序。

输入描述
输入第一行包含一个整数 N。

接下来 N 行每行包含一个字符串Si表示人名。

1≤N≤10

输出描述
输出共若干行,每行输出各种情况的人名。一行一种情况,每种情况的名字按照报名即输入顺序排序。

输入输出样例
示例
输入

3
xiaowang
xiaoA
xiaoli

输出

xiaowang xiaoA xiaoli
xiaowang xiaoli xiaoA
xiaoA xiaowang xiaoli
xiaoA xiaoli xiaowang
xiaoli xiaowang xiaoA
xiaoli xiaoA xiaowang

运行限制
最大运行时间:1s
最大运行内存: 128M

代码

import java.util.Scanner;
import java.util.Vector;

public class Main {

  static  int n;
  static Vector<String> name = new Vector<String>();
  static int[] order =new int[20];
  static boolean[] chosen =new boolean[20];

  static <object> void calc(int x) {

      if (x == n + 1) { //选够了m个数输出
          String ansTem = "";

          for (int i = 1; i <=n ; i++)

              ansTem += name.get(order[i]-1) + " ";

          System.out.println(ansTem);
          return;
      }

      for (int i = 1; i <= n; i++) {
          if (chosen[i]) continue;
          order[x] = i;
          chosen[i] =true;
          calc(x + 1);
          chosen[i] = false;
          order[x] = 0;
      }
  }

  public static void main(String[] args) {

      Scanner in = new Scanner(System.in);

      n = in.nextInt();

      for (int i = 0; i < n; i++) {

         String s;
          s=in.next();
          name.addElement(s);
      }
      calc(1);
  }
}

指数型枚举

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值