3.7练习题解

news2024/10/24 4:29:55

一共五道题:

1. PERKET:

 

观察容易发现n的值很小,所以我们可以考虑使用dfs的方法进行解答,首先我们可以考虑一共有n种配料,那么我们就可以考虑到可以选择1到n种配料数目,然后基于这个思路我们再对其进行判断当选择几种并且选择哪几种能够得到最小的酸甜度匹配,于是代码就如下:

#include<bits/stdc++.h>
using namespace std;
const int N=50;
int n,ans=1<<20,x=1,y=0;
int a[N],b[N],book[N];
void dfs(int c){
	 if(c==0){
	 	ans=min(ans,abs(x-y));
	 	return;
	 } 
	 for(int i=1;i<=n;i++){
	 	if(book[i]){
	 		x*=a[i];
	 		y+=b[i];
	 		--c;
	 		book[i]=0;
	 		dfs(c);
	 		book[i]=1;
	 		++c;
	 		x/=a[i];
	 		y-=b[i];
		 }
	 }
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i]>>b[i];
	}
	for(int i=1;i<=n;i++){
		x*=a[i];
		y+=b[i];
	}
	ans=min(ans,abs(x-y));
	for(int i=1;i<=n;i++){
		ans=min(ans,abs(a[i]-b[i]));
	}
	for(int i=2;i<n;i++){
	    memset(book,1,sizeof(book));
		x=1;
		y=0;
		dfs(i);
		
	}
	cout<<ans<<endl;
	return 0;
}

 引入了book数组来标记在dfs过程中已经被使用过的配料,然后先把选择一种和n种配料的情况给算出来并更新最小的ans,接下来再判断当选择的配料数目为2到n-1的时候,对应的最小ans,并利用dfs进行不断更新。

2.迷宫:

 这道题目就是最经典和典型的dfs模板题目了,直接上代码吧:

#include<iostream>
#include<cstring>
using namespace std;
int n,m,t;
int startx,starty,p,q;
const int N=10;
int book[50][50],a[50][50];
int ans=0;
void dfs(int x,int y){
	 if(x==p && y==q){
	 	++ans;
	 	return;
	 } 
	 int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
	 int tx,ty;
	 for(int i=0;i<=3;i++){
	 	tx=x+next[i][0];
	 	ty=y+next[i][1];
	 	if(tx < 1 || tx > n || ty < 1 || ty > m)
	 	continue;
	 	if(!book[tx][ty] && a[tx][ty]){
	 		book[tx][ty] = 1;
			 dfs(tx,ty);
		if(a[tx][ty]) book[tx][ty]=0;
		 }
	 }
}
int main(){
	cin >> n >> m >> t;
	cin >> startx >> starty >> p >> q;
	memset(book,0,sizeof(book));
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++)
		a[i][j]=1;
	}
	for(int i=1;i<=t;i++){
		int x,y;
		cin>>x>>y;
		a[x][y]=0;
	}
	dfs(startx,starty);
	cout<<ans<<endl;
	return 0;
}

利用一个a数组代表是否有陷阱,利用book数组表示对于同一种方案是否有走过同一个格子,在dfs中利用一个二维数组来表示接下来一步的上下左右并进行枚举,不过我至今没有想明白为什么这只能获得70分。 

3.借教室:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 1000010;
int n, m;
int w[N];//这个数组用来存储n天中每一天对应的可借出去的教室
int l[N], r[N], d[N];//l和r分别表示对应天数的差分端点,d数组则表示对应需要借出的教室
LL b[N];//当进行二分筛选的时候这一个数组就是拿来进行记录当订单数量为mid的时候每一天需要的教室数量
bool check(int mid)
{
    memset(b, 0, sizeof b);
    for (int i = 1; i <= mid; i ++ )
    {
        b[l[i]] += d[i];
        b[r[i] + 1] -= d[i];//对端点进行加减
    }
    for (int i = 1; i <= n; i ++ )
    {
        b[i] += b[i - 1];
        if (b[i] > w[i]) return false;//如果当天的需求大于所能提供的教室数量则说明要求的值在mid的左边
    }
    return true;
}
int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i ++ )
        scanf("%d", &w[i]);
    for (int i = 1; i <= m; i ++ )
        scanf("%d%d%d", &d[i], &l[i], &r[i]);

    int l = 0, r = m;
    while (l < r)
    {
        int mid = l + r + 1 >> 1;//我们的二分求出来的r是最后一份能恰好满足教室需求的订单,r+1则是第一个无法满足的订单,记得右移
        if (check(mid)) l = mid;
        else r = mid - 1;
    }

    if (r == m) puts("0");
    else printf("-1\n%d\n", r + 1);
    return 0;
}

 这道题目的方法就是差分加二分,订单的数量越多,那么剩余的空余教室的数量肯定会减少,因此我们考虑使用二分的方法进行查找,对于每一份订单,我们都有一个区间,在这个区间上加上订单所对应的借教室的数量,但是我们会发现题目当中,n和m的极限数据是10的6次方,如果对于每一个订单我们都将从第l天到第r天进行枚举并加上借教室的数量的话会导致tle,所以我们考虑使用差分的方式进行加速处理,这样处理的时间复杂度为O(n+m)logm。

以下是二分的两种模板:

bool check(int x) {/* ... */} // 检查x是否满足某种性质

// 区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用:
int bsearch_1(int l, int r)
{
    while (l < r)
    {
        int mid = l + r >> 1;
        if (check(mid)) r = mid;    // check()判断mid是否满足性质
        else l = mid + 1;
    }
    return l;
}
// 区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用:
int bsearch_2(int l, int r)
{
    while (l < r)
    {
        int mid = l + r + 1 >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    return l;
}

4.分巧克力:

这道题目的话 难度比排教室要小很多了,我们可以考虑使用二分来找到所给的巧克力总共可以分成的边长最大的数量大于k的答案,那么我们的代码可以这样去写:

#include<iostream>
using namespace std;
const int N=1e5+100;
int w[N],h[N];
int n,k;
bool pd(int x){
	int ans=0;
	for(int i=1;i<=n;i++){
		ans += (w[i]/x) * (h[i]/x);
	}
	if(ans>=k) return true;
	else return false;
}
int main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>w[i]>>h[i];
	}
	int l=1,r=100000;
	while(l<r){
		int mid=l+r+1>>1;
		if(pd(mid)) l=mid;
		else r=mid-1;
	}
	cout<<r<<endl;
	return 0;
}

5.技能升级

这是一道很难的题目,题解如下:

一定要记得开long long:

#include <iostream>
#include <cmath>
#define N 100005
using namespace std;
int n, m, l = 0, r = 1e6, mid, now, cnt, a[N], b[N];
long long ans;
long long sum (int r, int n, int t) // 求和
{
    int l = r - t * (n - 1);
    return (long long) (l + r) * n >> 1;
}
bool check (int x)
{
    long long res = 0;
    for (int i = 1; i <= n; i ++)
    {
        if (a[i] > x) // 前提条件
        {
            res += ceil ((double) (a[i] - x) / b[i]);
            // 累计第 i 个技能发动的次数
        }
    }
    return res <= m; // 判断是否合法
}
int main ()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i ++)
    {
        cin >> a[i] >> b[i];
    }
    while (l < r) // 二分
    {
        mid = l + r >> 1;
        if (check (mid)) // 如果 x = mid 合法
        {
            r = mid;
        }
        else
        {
            l = mid + 1;
        }
    }
    for (int i = 1; i <= n; i ++)
    {
        if (a[i] > l) // 前提条件
        {
            now = ceil ((double) (a[i] - l) / b[i]), cnt += now;
            // now 是第 i 个技能发动的次数,cnt 则是总共升级了多少次
            ans += sum (a[i], now, b[i]);
            // 总升级攻击力累加上右端点为 a[i],项数为 now,公差为 b[i] 的等差数列和
        }
    }
    cout << ans + (long long) l * (m - cnt); // 答案还要记得加上那些等于 l 的攻击力增加
    return 0;
}

也可以用另一种二分模板,代码如下:

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,ans;
const int N=1e3+100;
int a[N],d[N];
int sum(int An,int n,int dx){
	int A1=An-(n-1)*dx;
	return n*(A1+An)/2;
}
bool check(int x){
	 int cnt=0;
	 for(int i=1;i<=n;i++){
	    if(a[i]>x)	cnt += ceil( (double)(a[i]-x) / d[i]); 
	 }
      return cnt>=m;
}

signed main(){
    ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int l=0,r=1e6;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i]>>d[i];
	}
	while(l<r){
		int mid=l+r+1>>1;
		if(check(mid)) l=mid;
		else r=mid-1;
	}
	int cnt=0;
    for(int i=1;i<=n;i++){
    	if(a[i]>r){
    		int now=ceil((double)(a[i]-r)/d[i]);
    		cnt+=now;
    		ans += sum(a[i],now,d[i]);
		}
	}
	cout<<ans+(m-cnt)*r;
	return 0;	
}

感谢您的观看。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

评测本地部署的语音识别模型

1 引言 最近&#xff0c;朋友给我发来了一段音频&#xff0c;想转录成文字&#xff0c;并使用大型润色文本。音频中的普通话带有一定的口音&#xff0c;并且讲解内容较为专业&#xff0c;所以一般的语音识别工具很难达到较高的识别率。 于是试用了两个大模型。Whisper 是目前…

大数据背景下R语言lavaan在SEM中的高效应用

结构方程模型&#xff08;SEM&#xff09;是揭示系统内变量间复杂关系的强大工具。它利用图形化的方式&#xff0c;将多变量间的因果关系网展现得淋漓尽致&#xff0c;具备出色的数据分析能力和广泛的适用性。近年来&#xff0c;无论是在生态、进化、环境领域&#xff0c;还是在…

分类预测 | Matlab基于GWO-RBF灰狼算法优化径向基神经网络的分类预测

分类预测 | Matlab基于GWO-RBF灰狼算法优化径向基神经网络的分类预测 目录 分类预测 | Matlab基于GWO-RBF灰狼算法优化径向基神经网络的分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 Matlab基于GWO-RBF灰狼算法优化径向基神经网络的分类预测。基于灰狼算法(GWO…

Java定时调度范式定时操作

在 Java 中&#xff0c;我们可以使用各种方法来执行定时操作。这些操作包括执行任务、调度任务、执行重复任务等。下面将介绍几种常见的 Java 定时调度范式。 1. Timer 和 TimerTask Java 提供了 Timer 和 TimerTask 类&#xff0c;用于执行定时任务。 示例代码&#xff1a;…

腾讯云服务器和阿里云服务器价格测评_2024年费用大PK

2024年阿里云服务器和腾讯云服务器价格战已经打响&#xff0c;阿里云服务器优惠61元一年起&#xff0c;腾讯云服务器61元一年&#xff0c;2核2G3M、2核4G、4核8G、4核16G、8核16G、16核32G、16核64G等配置价格对比&#xff0c;阿腾云atengyun.com整理阿里云和腾讯云服务器详细配…

基于SpringBoot+Vue+ElementUI+Mybatis前后端分离管理系统超详细教程(三)

拓展学习——用XML方式写动态SQL实现数据库更新操作 前情回顾 前一章节我们学习了使用注解方式实现后端数据库增删改查操作 基于SpringBootVueElementUIMybatis前后端分离管理系统超详细教程&#xff08;二&#xff09; 本节课程接着拓展一下用xml配置文件方式来实现对数据…

练习 6 Web [极客大挑战 2019]HardSQL

[极客大挑战 2019]HardSQL 先尝试登录&#xff0c;查看报错信息 admin 111 password 1111 登录失败admin 111 password 1’or’1 登录成功 这里直接试了万能密码成功&#xff0c;复习一下&#xff0c;第一个 ’ 是为了闭合前面的sql语句&#xff0c;最后的1后面没有 ’ 是因为…

【数学建模】层次分析代码(python)

上一篇学习了层次分析的理论&#xff0c;今天用代码实现一下吧&#xff01; 判断矩阵的一致性检验 import numpy as np A np.array([[1,2,3,5],[1/2,1,1/2,2],[1/3,2,1,2],[1/5,1/2,1/2,1]]) n A.shape[0]#获取A的行 eig_val, eig_vecnp.linalg.eig(A)#计算方阵的特征值和特…

STM32CubeMX学习笔记16--- STM32内部FLASH

1. 内部FLASH简介 之前的文章中介绍过STM32F1利用SPI与外部FLASH&#xff08;W25QXX芯片&#xff09;通讯的例程&#xff0c;本例程将介绍STM32F1的内部FLASH&#xff0c;通过内部FLASH实现数据读写操作。 不同型号的STM32&#xff0c;其FLASH容量也有所不同&#xff0c;最小的…

【产品文档分类及撰写路径】

一、产品文档的分类 产品文档根据所处阶段和面相对象的差异大致可以分为三类&#xff1a; 商业需求文档 (BRD)&#xff1a;商业需求文档是面向公司高层和项目组&#xff0c;目的是为了获得资金、资源支持。市场需求文档 (MRD)&#xff1a;市场需求文档是面向运营和市场销售人员…

基于springboot+vue的旅游管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

微服务架构中实体类模块化设计与MyBatis-Plus注解浅析

引言 在微服务开发过程中&#xff0c;为了保证代码的整洁性和可维护性&#xff0c;我们通常会将VO&#xff08;视图值对象&#xff09;、DTO&#xff08;数据传输对象&#xff09;、DO&#xff08;领域对象&#xff09;等实体类独立组织成一个API模块。这样做的目的是实现代码…

大模型相关算法模型学习

对Transformer中Add&Norm层的理解-CSDN博客 GPT模型总结【模型结构及计算过程_详细说明】_gpt结构-CSDN博客 推荐30个以上比较好的中文nlp意图识别模型源码&#xff1f;-CSDN博客 Few-shot learning&#xff08;少样本学习&#xff09;入门 - 知乎 (zhihu.com) 零次学习…

Day15:技术架构、Maven、Spring Initializer、Spring全家桶、Spring IoC

侧重于服务端&#xff08;后端&#xff09;&#xff0c;不在意前端&#xff0c;了解一些前端即可&#xff09; 技术架构 &#xff08;把Spring设计的更简单好用了就是Spring Boot&#xff09; 开发环境&#xff08;Maven&#xff09; Maven maven通过brew安装的目录为&#x…

【uni-app小程序开发】实现一个背景色渐变的滑动条slider

最近做的一个用uni-app+vue2开发的微信小程序项目中要实现一个滑动进度控制条,如下图所示: 1. 滑动条需要渐变背景色 2. 滑块的背景色需要与当前位置滑动条的背景色一致(动态改变) 碰到这样的需求,我当然先是看看官方提供的slider组件和uView里的u-slider组件能不能满足…

YOLOv9电动车头盔佩戴检测,详细讲解模型训练

向AI转型的程序员都关注了这个号&#x1f447;&#x1f447;&#x1f447; 一、YOLOv9简介 YOLOv9是YOLO系列算法的最新版本。YOLO系列算法自2015年首次提出以来&#xff0c;已经在目标检测领域取得了显著的进展&#xff0c;以其快速和准确的特点而广受欢迎。 论文地址&#xf…

IPSEC VPN 网关模式实验

要求&#xff1a;FW1与FW3建立IPSEC通道&#xff0c;保证10.0.2.0/24网段能访问192.168.1.0/24网段 因为FW1与FW3都处于边界&#xff0c;所以使用网关部署模式来建立IPSEC VPN FW1 这里选择主模式跟隧道模式 FW3与FW1配置类似&#xff0c;与FW1的源目地址反过来&#xff0c;…

文心一言眼中的ChatGPT是什么样的

Q: 你好文心一言&#xff0c;请说一说你眼中的chatgpt A: 在我眼中&#xff0c;ChatGPT是一种非常先进和强大的自然语言处理模型&#xff0c;它展示了人工智能技术的显著进步。ChatGPT拥有出色的语言理解和生成能力&#xff0c;能够与用户进行流畅、自然的对话&#xff0c;并尝…

FreeRTOS_day2

作业&#xff1a;1.使用ADC采样光敏电阻数值&#xff0c;如何根据这个数值调节LED灯亮度。 2.总结DMA空闲中断接收数据的使用方法 打开DAM,允许接收外部设备数据&#xff0c;调用中断接收回调函数

【蓝桥杯】路径之谜(DFS)

一.题目描述 小明冒充 X 星球的骑士&#xff0c;进入了一个奇怪的城堡。 城堡里边什么都没有&#xff0c;只有方形石头铺成的地面。 假设城堡地面是 nn 个方格。如下图所示。 按习俗&#xff0c;骑士要从西北角走到东南角。可以横向或纵向移动&#xff0c;但不能斜着走&#x…