洛谷算法1-3 暴力枚举

目录

1 P2241统计方形

 2 三连击

 3 选数

4  P1088 [NOIP2004 普及组] 火星人

 5 P3799 小 Y 拼木棒 排列组合

 6 P2392 kkksc03考前临时抱佛脚

 7 P2036 [COCI2008-2009 #2] PERKET


1 P2241统计方形

思路:

  • 本题中,矩阵数量=正方形数量+长方形数量,得出正方形个数和矩阵个数即可求出长方形个数
  • 求正方形个数:正方形右下角i,j,取min(i,j)即为到这个点可能的正方形个数
  • 求矩阵个数,i*j
public static void main(String[] args) {Scanner scanner=new Scanner(System.in);int n = scanner.nextInt();int m= scanner.nextInt();// 1*1正方形long countZheng=0;long countJu=0;for (int i = 1; i <=n ; i++) {for (int j = 1; j <=m ; j++) {countZheng+=Math.min(i,j);countJu+= (long) i *j;}}System.out.print(countZheng+" ");System.out.println(countJu-countZheng);
}

 2 三连击

思路:

  • 将9个数分成三个三位数,要找到成比例的一组数,枚举出所有可能的数
  • 采用深度搜索,使用boolean数组判断该数是否被使用
  • 要记录三个三位数,因为题目中直接输出即可,不是先输出组数,所以不需要保存该组数据,使用一个number数组,前3位为第一个三位数,中间三位为第二个三位数,后三位为第三个三位数
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Scanner;public class P1618 {static Scanner scanner=new Scanner(System.in);static int A = scanner.nextInt();static int B = scanner.nextInt();static int C = scanner.nextInt();static boolean flags=false;public static void main(String[] args) {int[]number=new int[10];boolean[]flag=new boolean[10];// 深度搜索枚举所有情况digui(1,number,flag);if (!flags){System.out.println("No!!!");}}public static int judge(int m,int[] number){int sum=0;for (int i = 3*m-2; i <=3*m ; i++) {int ele=number[i];sum=sum*10+ele;}return sum;}public static void digui(int index,int[]number, boolean[]flag){if (index>=10){// 9位数全部使用完了 判断比例关系int one=judge(1,number);int two=judge(2,number);int three=judge(3,number);if (one*B==two*A && one*C==three*A && two*C==three*B){System.out.print(one+" ");System.out.print(two+" ");System.out.print(three);System.out.println();flags=true;}return;}for (int i = 1; i <= 9; i++) {if (!flag[i]){// 拼接这个数number[index]=i;flag[i]=true;digui(index+1,number,flag);// 回溯flag[i]=false;}}}
}

 3 选数

思路:

  • 组合,从一些数中选取一部分(子集),判断是否是素数
  • 递归深度搜索,深度为子集的个数
  • 该题中组合不可以重复,使用start来标记从哪里开始
import java.util.Scanner;public class P1036 {static int count=0;public static void main(String[] args) {Scanner scanner=new Scanner(System.in);int n = scanner.nextInt();int k = scanner.nextInt();int[] array=new int[n];int sum=0;boolean[] flags=new boolean[n];for (int i = 0; i < n; i++) {array[i]=scanner.nextInt();}digui(1,array,k,sum,flags,0);System.out.println(count);}public static void digui(int index,int[]array,int k,int sum,boolean[] flags,int start){if (index>k){// 已经选择够数量 判断sum是否是素数if (isPrime(sum)){count++;}return;}for (int i = start; i < array.length; i++) {if (!flags[i]){sum+=array[i];flags[i]=true;// 这里start是i+1而不是start+1 因为i指向的是当前数 i+1是之后的数 // start是第一次进入该循环开始的数 之后循环继续而start不变 会造成重复digui(index+1,array,k,sum,flags,i+1);flags[i]=false;sum-=array[i];}}}private static boolean isPrime(int sum) {for (int i = 2; i <= sum/i; i++) {if (sum%i==0){// 不是素数return false;}}return true;}
}

4  P1088 [NOIP2004 普及组] 火星人

思路:

  • 题目给出一个手指数,将其转换为数字,加上给定数之后,找到对应的排列数输出
  • 直接定位题目给定排列, i=array[index-1];
    • array是程序给定的一个排列数数组,array[index-1];是当前层数的值
    • 我们需要找到初始时给定的排列数,我们把i值赋给 num[index-1]
    • 在深度达到层数后,第一次找到的排列数即为给定排列数
  • System.exit(0);直接结束程序,return只能结束方法,在递归深度很深时,程序依然需要很长时间
import java.util.Arrays;
import java.util.Scanner;public class P1088 {static int count=0;static int[]array;static int M;static int target;static boolean flag=false;public static void main(String[] args) {new Thread(null, () -> {Scanner scanner=new Scanner(System.in);int N = scanner.nextInt();M = scanner.nextInt();// array是火星人的手指array=new int[N];for (int i = 0; i < N; i++) {array[i]=scanner.nextInt();}// 1.将手指转为所代表的数字boolean[] flags=new boolean[N+1];int[]num=new int[N];// 2.加上小整数// 3.转为手指数digui(1,flags,N,num);scanner.close();},"t",2<<24).start();// 2<<24 是stackSize 测试样例第二个爆栈,改一下虚拟机栈内存大小}/*** 全排列* @return*/public static void digui(int index,boolean[]flags,int N,int[]num)  {if (index>N){count++;if (count==1){// 第一次找到的排列数 皆为输入的数// 计算目标值target=count+M;}if (count==target){for (int ele : num) {System.out.print(ele+" ");}flag=true;}return;}for (int i = 1; i <= N; i++) {if (count==0){// count==0 还没有找到第一个排列的数// array是给定的数组 1 2 3 4 5 多次递归之后 直接到达给定的位置i=array[index-1];}if (!flags[i]){num[index-1]=i;flags[i]=true;digui(index+1,flags,N,num);flags[i]=false;if (flag){// 结束System.exit(0);}}}}
}

 5 P3799 小 Y 拼木棒 排列组合

思路:

  • n根木棒中挑出4根组成正三角形(3条边都相等,则有两根木棒长度相等,另外两根木棒相加为前两根木棒的长度
  • 纯暴力解法会TLE,采用数学中组合的方式,
    • 首先统计每个长度出现的次数
    • 外层循环,挑选2个长度相等的木棒,注意:木棒长度需要大于2,否则两根木棒相加之和大于此木棒,在数量为n的木棒中,挑选两个a=C(counts[i],2) n*(n-1)/2
    • 内层循环,一根木棒长度为j,另一根木棒长度为i-j,如果j=i-j,则需要在长度为j的木棒中挑选两根,c=C(count[j],2),注意该长度为j的木棒个数需要>=2个;如果j!=i-j,则需要在长度为j的木棒中挑选一根,长度为i-j的木棒中挑选一根,c=C(counts[j],1)*C(counts[i-j],1);
    • 则 count+=a*c;注意需要每次都取模,以免超出范围

细节:运算的优先顺序

  • count += a * c;
  • 首先计算 a * c 的结果,然后将这个结果加到 count 上。
  • 接着对 count 进行取模运算,即 count %= (int) mod;,这会确保 count 的值不会超过 mod
  • count += a * c % mod;
  • 首先计算 a * c 的结果,然后对这个结果进行取模运算,得到 (a * c) % mod
  • 然后将这个取模结果加到 count 上。
import java.util.Scanner;public class P3799 {static double mod = Math.pow(10, 9) + 7;public static void main(String[] args) {Scanner scanner=new Scanner(System.in);int n = scanner.nextInt();int[]array=new int[n];int[]counts=new int[n];// 记录最大长度int maxLength=0;int menLength=Integer.MAX_VALUE;for (int i = 0; i < n; i++) {array[i]=scanner.nextInt();counts[array[i]]++;maxLength=Math.max(maxLength,array[i]);menLength=Math.min(menLength,array[i]);}int count=0;// 外层循环 拿到两个长度为i值木棒 i和j是长度 counts.length是有多少种长度不同的元素 无法代表最长长度for (int i = menLength+1; i <= maxLength; i++) {// 排列组合的方式 在长度等于i的木棒中挑两个if (counts[i]<2){continue;}int a=C(counts[i],2);// 内层循环 拿到两根长度和为i的木棒for (int j = menLength; j <= i/2; j++) {int c;// 两根木棒相等 则总长度为j的木棒中挑2个if (j==i-j){if (counts[j]<2){continue;}c=C(counts[j],2);}else{// 两根木棒长度相等 则总长度为j的木棒中挑1个 i-j的木棒中挑一个c=C(counts[j],1)*C(counts[i-j],1);}// 注意每次计算完都要取模count+=a*c;count %= (int) mod;}}System.out.println(count);;}public static int C(int  n,int k){if (k==2){// 从n个数中取2个数return n*(n-1)/2;}else{return n;}}
}

排列公式:

  • A 有顺序

组合公式:

  • C 无顺序
  • C35=5*4*3/1*2*3
  • C62=6*5/1*2

 6 P2392 kkksc03考前临时抱佛脚

思路:

  • 每次选择让时间加到较小值的思想不成立
  • 每个科目独立,则进行多次循环,算出每个科目需要的最短时间
  • 左右脑同时学习,则本道题要不左脑,要不右脑,两种情况可以类比为背包问题,在左右脑的时间都接近t/2时,所用时间最短效率最高,则背包容量为t/2,每道题为所放物品,求怎样放时长最接近t/2
  • 每个科目所需的时间为Math.max(v,t-v);
  • v为背包所求时间,t-v为剩余题目的时间

细节:背包容量设置为sumTime / 2 + 1,这样可以避免0容量

import java.util.Arrays;
import java.util.Scanner;public class P2392 {public static void main(String[] args) {Scanner scanner=new Scanner(System.in);int[] array=new int[4];for (int i = 0; i < 4; i++) {array[i]=scanner.nextInt();}int sum=0;for (int value : array) {// 将时间比作价值int[] values = new int[value];// 总时间int sumTime = 0;for (int j = 0; j < values.length; j++) {values[j] = scanner.nextInt();sumTime += values[j];}// 比作01背包问题 当左右脑时间最接近t/2时 效率高int[][] dp = new int[value][sumTime / 2 + 1];for (int j = 0; j < sumTime / 2+1; j++) {if (j >= values[0]) {dp[0][j] = values[0];}}for (int j = 1; j < value; j++) {for (int k = 0; k < sumTime / 2 + 1; k++) {if (k < values[j]) {dp[j][k] = dp[j - 1][k];} else {dp[j][k] = Math.max(dp[j - 1][k], dp[j - 1][k - values[j]] + values[j]);}}}sum += Math.max(dp[value - 1][sumTime / 2], sumTime - dp[value - 1][sumTime / 2]);}System.out.println(sum);}
}

 7 P2036 [COCI2008-2009 #2] PERKET

思路

  • 本题中说至少使用一种配料,即可能使用一种,两种...n种,我们要找到酸度和苦读绝对差最小的组合,采用dfs深度搜索
  • 注意:因为配料数目不同,可以多次深度搜索,通过层数来决定每次搜索的组合数
import javax.sound.midi.SysexMessage;
import java.util.Scanner;public class P2036 {static int result=Integer.MAX_VALUE;public static void main(String[] args) {Scanner scanner=new Scanner(System.in);int n = scanner.nextInt();int[][] array=new int[n][2];for (int i = 0; i < n; i++) {array[i][0] = scanner.nextInt();array[i][1] = scanner.nextInt();}int s=1;int b=0;boolean[]flags=new boolean[n];// n次深度搜索 每次深度不同for (int i = 1; i <= n; i++) {dfs(i,1,array,0,flags,s,b);}System.out.println(result);}
// num是本次深度搜索的层数(组合数)  index是当前递归的层数public static void dfs(int num,int index,int[][]array,int start,boolean[]flags,int s,int b){if (index>num){int abs = Math.abs(s - b);if (abs<result){result=abs;}return ;}for (int i = start; i <array.length ; i++) {if (!flags[i]){s*=array[i][0];b+=array[i][1];flags[i]=true;dfs(num,index+1,array,i+1,flags,s,b);flags[i]=false;s/=array[i][0];b-=array[i][1];}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/14935.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSS Overflow 属性详解:控制内容溢出的利器

在前端开发中&#xff0c;处理内容溢出是一个常见的需求。CSS 提供了 overflow 属性&#xff0c;帮助我们控制当内容超出元素框时的显示方式。本文将详细介绍 overflow 属性的各种取值及其应用场景。 1. 什么是 overflow 属性&#xff1f; overflow 属性用于控制当元素的内容…

链表和 list

一、单链表的模拟实现 1.实现方式 链表的实现方式分为动态实现和静态实现两种。 动态实现是通过 new 申请结点&#xff0c;然后通过 delete 释放结点的形式构造链表。这种实现方式最能体 现链表的特性&#xff1b; 静态实现是利用两个数组配合来模拟链表。一个表示数据域&am…

面向对象程序设计-实验3

题目1 &#xff08;给出题目描述&#xff09;设计一个类CRectangle 代码清单&#xff1a; #include<iostream> using namespace std; class CRectangle { public: CRectangle() { m_l1.0; m_w1.0; } void get() { cin>>m_l; if(m_l>50) { m_l1.0; } cin&g…

2025.1.8(qt图形化界面之消息框)

笔记&#xff08;后期复习补充&#xff09; 作业 1> 手动将登录项目实现&#xff0c;不要使用拖拽编程 并且&#xff0c;当点击登录按钮时&#xff0c;后台会判断账号和密码是否相等&#xff0c;如果相等给出登录成功的提示&#xff0c;并且关闭当前界面&#xff0c;发射一…

windows10 wsa 安卓子系统终结版

windows10 wsa 安卓子系统终结版 链接&#xff1a;https://pan.xunlei.com/s/VOIdoPPmqdUcgw3daFSbh2dAA1?pwdbe3r# windows10 wsa 安卓子系统终结版&#xff0c;包含三个文件. 1: windows10 wsa v2407.40000.4.0 x64 安卓子系统终结版。 2: Apk lnstaller v1.7 用于识别A…

计算机网络应用层:模型、系统与协议全解析!!!

应用层 应用层对应用程序的通信提供服务 应用层协议定义: 应用进程交换的报文类型&#xff0c;请求还是响应? 各种报文类型的语法&#xff0c;如报文中的各个字段及其详细描述&#xff0c; 字段的语义&#xff0c;即包含在字段中的信息的含义。 进程何时、如何发送报文&#x…

【分布式理论8】分布式调用之:四种IO模型

文章目录 一. 四种IO模型1. 同步阻塞 IO&#xff08;Blocking IO&#xff09;2. 同步非阻塞 IO&#xff08;Non-blocking IO&#xff09;3. IO 多路复用&#xff08;IO Multiplexing&#xff09;4. 异步 IO&#xff08;Asynchronous IO&#xff09;在 RPC 中的作用5. 总结 选择…

元宇宙中的隐私与数据保护:Facebook 的挑战与机遇

随着数字技术的飞速发展&#xff0c;元宇宙&#xff08;Metaverse&#xff09;正逐渐成为未来互联网的新舞台。Meta&#xff0c;作为这一领域的先行者&#xff0c;正面临着隐私与数据保护的双重挑战。本文将探讨 Meta 在元宇宙中的隐私与数据保护问题&#xff0c;并分析其可能的…

Word中Ctrl+V粘贴报错问题

Word中CtrlV粘贴时显示“文件未找到&#xff1a;MathPage.WLL”的问题 Word的功能栏中有MathType&#xff0c;但无法使用&#xff0c;显示灰色。 解决方法如下&#xff1a; 首先找到MathType安装目录下MathPage.wll文件以及MathType Commands 2016.dotm文件&#xff0c;分别复…

Stability AI 联合 UIUC 提出单视图 3D 重建方法SPAR3D,可0.7秒完成重建并支持交互式用户编辑。

Stability AI 联合 UIUC 提出一种简单而有效的单视图 3D 重建方法 SPAR3D&#xff0c;这是一款最先进的 3D 重建器&#xff0c;可以从单视图图像重建高质量的 3D 网格。SPAR3D 的重建速度很快&#xff0c;只需 0.7 秒&#xff0c;并支持交互式用户编辑。 相关链接 论文&#xf…

Spring Cloud 04 - 负载均衡和外部服务访问

Ribbon & Feign 文章目录 Ribbon & Feign一&#xff1a;Ribbon负载均衡1&#xff1a;介绍 2&#xff1a;ribbon的五大核心组件二&#xff1a;Feign外部接口访问1&#xff1a;Feign概述2&#xff1a;Feign vs OpenFeign3&#xff1a;使用示例3.1&#xff1a;注解支持3.2…

力扣--链表

相交链表 法一&#xff1a; 把A链表的节点都存HashSet里&#xff0c;遍历B链表找相同的节点 法二&#xff1a; 把A、B指针都移到末尾&#xff0c;再同时往回走&#xff0c;每次往回走都比较 当前节点的下一节点&#xff08;a.next b.next ?)是否相同&#xff0c;当不相同…

antd pro常见代码示例-ProTable

1、protable使用 这是antd Pro 封装的一个table组件&#xff0c;提供了很多好用的方法&#xff0c; proTable地址&#xff1a; protable官网 代码示例&#xff1a; <ProTableactionRef{actionRef}pagination{{ //分页设置defaultPageSize: 10,showQuickJumper: true,sh…

【C++】异常

前言 本篇博客我们来看下C有关异常的处理&#xff0c;了解下异常有关的知识 &#x1f493; 个人主页&#xff1a;小张同学zkf ⏩ 文章专栏&#xff1a;C 若有问题 评论区见&#x1f4dd; &#x1f389;欢迎大家点赞&#x1f44d;收藏⭐文章 ​ 目录 1.异常的概念及使用 1.1异…

操作系统—进程与线程

补充知识 PSW程序状态字寄存器PC程序计数器&#xff1a;存放下一条指令的地址IR指令寄存器&#xff1a;存放当前正在执行的指令通用寄存器&#xff1a;存放其他一些必要信息 进程 进程&#xff1a;进程是进程实体的运行过程&#xff0c;是系统进行资源分配和调度的一个独立单位…

NIO--ByteBuffer组件

文章目录 概述ByteBuffer 正确使用姿势ByteBuffer 结构ByteBuffer 常见方法分配空间向 buffer 写入数据从 buffer 读取数据mark 和 reset字符串与 ByteBuffer 互转Scattering ReadsGathering Writes ⚠️ Buffer 的线程安全 概述 ByteBuffer就是缓冲区&#xff0c;作为channel…

软件工程的熵减:AI如何降低系统复杂度

软件开发的世界&#xff0c;如同一个不断膨胀的宇宙。随着功能的增加和时间的推移&#xff0c;代码库越来越庞大&#xff0c;系统复杂度也随之水涨船高。代码膨胀、维护困难、开发效率低下等问题困扰着无数开发者。这不禁让人联想到物理学中的“熵增”原理——一个孤立系统的熵…

xss闯关

BUU上的[第二章 web进阶]XSS闯关 第一关 第一关很简单&#xff0c;没有任何过滤&#xff0c;直接输入&#xff1a;<script>alert()</script>即可。 第二关 第二关可以输入xss和<script>alert()</script>分别查看页面源代码&#xff0c;看看哪里变了…

Postman接口测试:postman设置接口关联,实现参数化

postman设置接口关联 在实际的接口测试中&#xff0c;后一个接口经常需要用到前一个接口返回的结果&#xff0c; 从而让后一个接口能正常执行&#xff0c;这个过程的实现称为关联。 在postman中实现关联操作的步骤如下&#xff1a; 1、利用postman获取上一个接口指定的返回值…

从算法到落地:DeepSeek如何突破AI工具的同质化竞争困局

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;Linux网络编程 &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 ​ Linux网络编程笔记&#xff1a; https://blog.cs…