暴力枚举

 

目录

0、枚举 简介

 1、洛谷 P2241 统计方形(数据加强版)

2、洛谷 P3392 涂国旗

3、 Java 大学B 组试题D: 数的分解


0、枚举 简介

枚举是基于已有知识来猜测答案的一种问题求解策略。枚举的思想是不断地猜测,从可能的集合中一一尝试,然后再判断题目的条件是否成立。

要点

  1. 给出解空间

    建立简洁的数学模型。
    枚举的时候要想清楚:可能的情况是什么?要枚举哪些要素?

  2. 减少枚举的空间

    枚举的范围是什么?是所有的内容都需要枚举吗?
    在用枚举法解决问题的时候,一定要想清楚这两件事,否则会带来不必要的时间开销。

  3. 选择合适的枚举顺序
    根据题目判断。比如例题中要求的是最大的符合条件的素数,那自然是从大到小枚举比较合适。

 1、洛谷 P2241 统计方形(数据加强版)

oj:https://www.luogu.com.cn/problem/P2241

标签:数论,数学枚举,暴力

package 暴力枚举;

import java.util.Scanner;

public class P2241统计方形 {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n=in.nextInt();
		int m=in.nextInt();
		long zheng=0,juXing=0;//int:+-2.1*10^9;long:+-9.2*10^18;long才能accept 100%
		for(int i=1;i<=n;i++) {
			for(int j=1;j<=m;j++) {
				zheng+=Math.min(i, j);
			}
		}
		for(int i=1;i<=n;i++) {
			for(int j=1;j<=m;j++) {
				juXing+=i*j;
			}
		}
		System.out.println(zheng+" "+(juXing-zheng));
	}
}
/*
一、算正方形的个数
1.如果我们固定了正方形的右下角(i,j),你能不能算出此时可能的正方形的个数?
2.显然,此时答案为Min(i,j).
3.所以可以枚举右下角,计算此时答案,求和即可。

二、算长方形个数
1.其实算长方形并不常见,但算矩形大家应该经常遇到,所以如果你会算矩形,再联系第一个问题,
那答案就转化为 矩形个数-正方形个数.
2.像求解正方形个数一样,固定矩形右下角(i,j),显然此时矩形个数为i*j.
3.同理,求和即可.
*/

2、洛谷 P3392 涂国旗

oj:https://www.luogu.com.cn/problem/P3392

标签:模拟枚举,暴力

package 暴力枚举;

import java.util.Scanner;

public class P3392涂国旗 {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n=in.nextInt();
		int m=in.nextInt();
		char[][] arr=new char[n][m];
		String s = null;
		int cnt=0,k,g,ans=2500;//ans初始化成一个很大的数
		for(int i=0;i<n;i++) {//因为没有直接输入char[][]的next(),所以转换为输入字符串
			s=in.next();
			arr[i]=s.toCharArray();//将输入字符串转换为数组,即第i行数
		}
		for(int i=0;i<n-2;i++) {//由于白色下面还有蓝色和红色,所以i(白与蓝的边界)枚举到(n-3)
			for(int j=i+1;j<n-1;j++) {//j(蓝与红的边界)至少要比i大1,同理枚举到(n-2),这样可以减少枚举次数
				cnt=0;
				//壮观地枚举三个区域
				for(k=0;k<=i;k++)for(g=0;g<m;g++)if(arr[k][g]!='W')cnt++;
				for(k=i+1;k<=j;k++)for(g=0;g<m;g++)if(arr[k][g]!='B')cnt++;
				for(k=j+1;k<=n-1;k++)for(g=0;g<m;g++)if(arr[k][g]!='R')cnt++;
				ans=Math.min(ans,cnt);//更新答案
			}
		}
		System.out.println(ans);
	}
}

3、 Java 大学B 组试题D: 数的分解

第十届蓝桥杯大赛软件类省赛   本题总分:10 分
【问题描述】
把2019 分解成3 个各不相同的正整数之和,并且要求每个正整数都不包含数字2 和4,一共有多少种不同的分解方法?注意交换3 个整数的顺序被视为同一种方法,例如1000+1001+18 和1001+1000+18 被视为同一种。
【答案提交】这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

思路:主要还是考虑到不同顺序的三个数只能算一种,所以可以i从1~2019,j从i+1到2019,k从j+1到2019,这样i,j,k三个数就是呈递增顺序来遍历就不存在重复问题了。

package javaB省赛2019;
import java.util.Scanner;
//思路:因为要求3个各不相同的正整数的分解方法。
//i,j,k升序排序肯定不同,依次取i,j,k;且复杂度小
public class D数的分解 {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int k,cnt=0;
		for(int i=1;i<=2016;i++) {
			for(int j=i+1;j<=2016;j++) {
				k=2019-i-j;
				if(k<=0)break;
				if(k>j&&isOk(i)&&isOk(j)&&isOk(k)) {
					System.out.println(i+" "+j+" "+k);
					cnt++;
				}
			}
		}
		System.out.println(cnt);
	}
	//判断某数是否包含数字2 和4
	static boolean isOk(int n) {
		if(n/1000==2||n/1000==4)return false;
		else if(n/100%10==2||n/100%10==4)return false;
		else if(n/10%10==2||n/10%10==4)return false;
		else if(n%10==2||n%10==4)return false;
		else return true;
	}
}

输出:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值