[NOIP2016 普及组] 魔法阵(枚举的典型例题,值得一看)

在透视这道题之前,先用一道小题来练练手

密码锁(这道题是我根据魔法阵改的)

Description

叮当在探索迷宫时被一扇大门挡住了去路,门上刻画了很多乱七八糟的数字,门被锁上了,无法打开,但是门上给出了提示:

1:正确按下门上的三个数字即可打开大门;

2:这三个数必须满足递增排列按下;

3:后两个数之差比前两个数之差的8倍还要大。

现在叮当想知道一共有多少种可能的情况来确定开门时间(对于门上不同位置的相同数字算不同的情况)。

Format
Input

第一行一个正整数n表示门上的数字(3<=n<=10000)。

第二行为n个正整数,表示每个数的值x(1<=x<=10000)。

Output

密码的可能情况。

Samples
Sample Input 1
11
2 2 3 3 4 4 4 13 13 13 13
Sample Output 1
40
Limitation

(2,3,13)共16种

(3,4,13)共24种

一共40种可能情况

对于30%的数据,3<=n<=500,1<=x<=500;

对于60%的数据,3<=n<=1500,x<=1500;

对于100%的数据,3<=n<=10000,1<=x<=10000;

思路

该题的本质就是选择三个数a,b,c,要求满足:

a<b<c,并且8*(b-a)<c-b很容易想到依次枚举a,b,c,由于是从小到大,我们可以把数组排序后,依次枚举,然后判断是否满足上面条件,时间复杂度为O(n^3)。

由于我们枚举的数可能不满足第二个条件,即枚举了很多无效的答案,所以效率很低,那么我们是 否可以保证我们在枚举的时候a,b,c, 一定就满足两个条件呢?

我们可以枚举a,然后枚举t=b-a,那么得到b的值 为a+t,可以计算出c的最小值为a+9*t+1。

如果按照这种方法枚举,那么我们的枚举方法就 不再是依次枚举每一个数了,因为我们没有办法直 接知道a+9*t+1到底是哪一个数。 那么我们可以换一种方法,枚举值,数的范围是 (1,10000),那么我们可以直接枚举1-10000,每个数 不止一种,先统计每种数的数量,再用到乘法原理 ,把a,b,c三个数的数量相乘。 在枚举的时候注意a,b,c的范围,尽量保证没有无 效的枚举,为了方便,其实我们可以先枚举t=b-a, 再枚举a,这样t的范围是[1,9*t+2<=m],a的范围是 [1,m-9*t-1],可以再枚举大的值k,k的范围是 [1,a+9*t+k<=m],而c=a+9*t+k。

这种枚举的方法,保证了枚举的所有数都是满足 题目给定条件的,时间复杂度相对于暴力枚举a,b,c 提高了81倍左右。

但是上述做法仍然不是该题的正解,该题的正解需要 用到继承种的单调性。 比如3 4 100满足条件,那么2 3 100,1 3 100是 不是仍然满足条件,也就是说,对于较大的a和b, 存在x个满足条件的c,那么对于比当前a,b小的情况 ,得到满足条件的c的个数y,那么实际上总的满足 条件的情况c一共有x+y个。 所以我们可以从大到小枚举a,累加当前情况下的 c的数量,当下一次枚举a的时候,答案为当前答案 加上前面的累加和,这样我们就没有必要再去枚举大于这个条件了,省去了一层循环。

ACcode
#include<bits/stdc++.h>
using namespace std;

int num[10100],maxn=INT_MIN;
int main(){
    int n,tmp;
    cin>>n;
    for (int i=0;i<n;i++){
    	cin>>tmp;
    	num[tmp]++;
    	maxn=max(maxn,tmp);
	}
	long long cnt=0;
    for (int t=1;9*t+2<=maxn;t++){
    	int s=0;
    	for (int a=maxn-9*t-1;a>=1;a--){
    		int b=a+t,c=b+8*t+1;
    		s+=num[c];
    		cnt+=num[a]*num[b]*s; 
		}
	} 
    cout<<cnt;
	return 0;
}

这时候就有人问了,密码锁跟魔法阵有什么关系呢?

别慌,我们先把魔法阵的题目看了。

题目背景

NOIP2016 普及组 T4

题目描述

六十年一次的魔法战争就要开始了,大魔法师准备从附近的魔法场中汲取魔法能量。

大魔法师有 m 个魔法物品,编号分别为 1,2,…,m。每个物品具有一个魔法值,我们用 Xi​ 表示编号为 i 的物品的魔法值。每个魔法值 Xi​ 是不超过 n 的正整数,可能有多个物品的魔法值相同。

大魔法师认为,当且仅当四个编号为 a,b,c,d 的魔法物品满足 Xa​<Xb​<Xc​<Xd​,Xb​−Xa​=2(Xd​−Xc​),并且Xb​−Xa​<(Xc​−Xb​)/3 时,这四个魔法物品形成了一个魔法阵,他称这四个魔法物品分别为这个魔法阵的 A 物品,B 物品,C 物品,D 物品。

现在,大魔法师想要知道,对于每个魔法物品,作为某个魔法阵的 A 物品出现的次数,作为 B 物品的次数,作为 C 物品的次数,和作为 D 物品的次数。

输入格式

第一行包含两个空格隔开的正整数 n,m。

接下来 m 行,每行一个正整数,第 i+1 行的正整数表示 Xi​,即编号为 i 的物品的魔法值。

保证 1≤n≤15000,1≤m≤40000,1≤Xi≤n。每个 Xi​ 是分别在合法范围内等概率随机生成的。

输出格式

共 m 行,每行 4 个整数。第 i 行的 4 个整数依次表示编号为 i 的物品作 为 A,B,C,D 物品分别出现的次数。

保证标准输出中的每个数都不会超过 10^9。每行相邻的两个数之间用恰好一个空格隔开。

样例 #1

样例输入 #1

30 8
1
24
7
28
5
29
26
24

样例输出 #1

4 0 0 0
0 0 1 0
0 2 0 0
0 0 1 1
1 3 0 0
0 0 0 2
0 0 2 2
0 0 1 0

样例 #2

样例输入 #2

15 15
1 
2 
3 
4 
5
6 
7 
8 
9
10
11
12
13
14
15

样例输出 #2

5 0 0 0
4 0 0 0
3 5 0 0
2 4 0 0
1 3 0 0
0 2 0 0
0 1 0 0
0 0 0 0
0 0 0 0
0 0 1 0
0 0 2 1
0 0 3 2
0 0 4 3
0 0 5 4
0 0 0 5

提示

【样例解释 1】

共有 5 个魔法阵,分别为:

物品 1,3,7,6,其魔法值分别为 1,7,26,29

物品 1,5,2,7,其魔法值分别为 1,5,24,26

物品 1,5,7,4,其魔法值分别为 1,5,26,28

物品 1,5,8,7,其魔法值分别为 1,5,24,26

物品 5,3,4,6,其魔法值分别为 5,7,28,29

以物品 5 为例,它作为 A 物品出现了 1 次,作为 B 物品出现了 3 次,没有作为 C 物品或者 D 物品出现,所以这一行输出的四个数依次为 1,3,0,0。

此外,如果我们将输出看作一个 m 行 4 列的矩阵,那么每一列上的 m 个数之和都应等于魔法阵的总数。所以,如果你的输出不满足这个性质,那么这个输出一定不正确。你可以通过这个性质在一定程度上检查你的输出的正确性。

【数据规模】

读完题后你看哈,密码锁是要求按下三个数字,且有两个要求,即枚举三个数字,而魔法阵是要求四个魔法物品的值满足三个要求,是不是差不多的呢,

先魔改一下这三个要求

设t=xd−xc

所以②可化为xb−xa=2t ④

将④代入③

2t<(xc−xb)/3

移项一下,就变成

6t<xc−xb ⑤

再魔改一下

设6t+k=xc−xb(就是把差的部分补上去)

所以就有了这个图:

 既然有了这个图,那是不是就可以按照密码锁的套路来枚举了呢?只不过是要先枚举t,再在t的循环内正着枚举D和倒着枚举A就可以了。

首先由上图易得t的范围是1<=t<=(n-1)/9,并且还可以得到C=D-t。因为让A,B,C,D满足条件的最小的k是1,所以就有A=D-9t-1,B=D-7t-1;

其次就要看枚举D和枚举A的范围,首先是D:由上图可知D的max是n,而最小值则是当k=1且A=1的时候,所以D的最小值为9∗t+2,再小是无法组成魔法阵的。然后是A:A的最小值显然是1,最大值则是在D取到最大值,也就是n的时候,所以A的最大值就是n-9t-1。

范围知道了,那就直接求不就完了?所以这道题是非常非常简单的啦

ACcode

#include<bits/stdc++.h>
#define LL long long
using namespace std;

LL sum[41000],maxn=INT_MIN;
LL cmp[41000];
LL a[15100],b[15100],c[15100],d[15100];
int main(){
    int m,n;
    cin>>m>>n;
    for (int i=0;i<n;i++){
    	cin>>cmp[i];
    	sum[cmp[i]]++;
    	maxn=max(maxn,cmp[i]);
	}
    for (int t=1;9*t+1<=m;t++){
    	LL s=0;
		for (int d1=9*t+2;d1<=m;d1++){
			int c1=d1-t,b1=c1-6*t-1,a1=b1-2*t;
			s+=sum[a1]*sum[b1];
			d[d1]+=s*sum[c1];
			c[c1]+=s*sum[d1];
		}//
		s=0;
    	for (int a1=m-9*t-1;a1>=1;a1--){
    		int b1=a1+2*t,c1=b1+6*t+1,d1=c1+t;
    		s+=sum[d1]*sum[c1];
    		a[a1]+=s*sum[b1];
    		b[b1]+=s*sum[a1];
		}//
	}
	for (int i=0;i<n;i++){
		cout<<a[cmp[i]]<<" "<<b[cmp[i]]<<" "<<c[cmp[i]]<<" "<<d[cmp[i]]<<endl;
	}
	return 0;
}

看了这么久,作者也写了这么久,能不能点一个赞,在收藏一下呢?最好的话在点个关注吧

谢谢啦!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WebGIS开发常用的JS库:VUE/React/Angular对比

Angular: 作用&#xff1a; Angular是一个完整的基于TypeScript的Web应用开发框架&#xff0c;主要用于构建单页Web应用&#xff08;SPA&#xff09;。它适用于大型和复杂的项目&#xff0c;具有强大的组件集合和丰富的文档。 架构&#xff1a; Angular采用组件化的方式&am…

【DC-DC】世微AP5192 LED恒流IC 摩托电动车货车 12-80V 1.5A 有极输入 电源驱动芯片

产品描述 AP5192是一款PWM工作模式,效率高、简单、内置功率MOS管&#xff0c;适用于4.5-100V输入的高精度降压LED恒流驱动芯片。电流1.5A。AP5192可实现线性调光和PWM调光&#xff0c;线性调光脚有效电压范围0.55-2.6V.AP5192 工作频率可以通过RT 外部电阻编程来设定&#xff0…

[经验] 动车盒饭价格2022 #其他#职场发展

动车盒饭价格2022 1、动车盒饭 近年来&#xff0c;随着中国高速铁路的发展&#xff0c;动车盒饭也成为了不可忽视的一份美食。它不仅解决了旅途中的饮食需求&#xff0c;还体现了中国美食文化的多样性和可口。 动车盒饭是一种便捷且美味的餐食&#xff0c;在火车上也不失为一…

胶原蛋白市场研究:预计2029年将达到27亿美元

胶原蛋白是一种白色、无支链的纤维状蛋白&#xff0c;是细胞外间质蛋白质的主要成分&#xff0c;占人体总蛋白质的25%到30%。 按胶原蛋白来源划分&#xff0c;可分为天然胶原蛋白和人工合成的胶原蛋白&#xff0c;后者以重组类人胶原蛋白为主&#xff0c;而重组类人胶原蛋白又可…

失败了,又继续失败了

这是一个普通的老人在小县城坚持写作的故事。与很多人的老年生活不同&#xff0c;78岁的舒绍平每天过着规律的写作生活&#xff0c;不做家务的时候&#xff0c;他便坐在书房&#xff0c;打开笔记本电脑&#xff0c;时断时续地敲字写作。 年轻时&#xff0c;他当过老师&#xf…

五种多目标优化算法(MOJS、MOGWO、NSWOA、MOPSO、NSGA2)性能对比,包含6种评价指标,9个测试函数(提供MATLAB代码)

一、5种多目标优化算法简介 1.1MOJS 1.2MOGWO 1.3NSWOA 1.4MOPSO 1.5NSGA2 二、5种多目标优化算法性能对比 为了测试5种算法的性能将其求解9个多目标测试函数&#xff08;zdt1、zdt2 、zdt3、 zdt4、 zdt6 、Schaffer、 Kursawe 、Viennet2、 Viennet3&#xff09;&#xff0…

C++学习Day08之函数模板

目录 前言一、程序及输出1.1 不使用函数模板1.2 使用函数模板1.2.1 自动类型推导1.2.2 显示指定类型 二、分析与总结 前言 C 函数模板是一种通用编程技术&#xff0c;允许您编写通用的函数代码&#xff0c;以适用于不同类型的数据。 一、程序及输出 1.1 不使用函数模板 每一…

【riscv】使用qemu运行riscv裸机freestanding程序

文章目录 1. 运行显示2. 工具准备3. 裸机代码和编译3.1 源码3.2 编译 4. 使用qemu仿真运行riscv裸机程序 1. 运行显示 详见左下角&#xff0c; 运行时串口输出的字符 A ; 2. 工具准备 # for riscv64-linux-gnu-gcc sudo apt-get install gcc-riscv64-linux-gnu# for qemu-s…

【RT-DETR有效改进】大核注意力 | LSKAttention助力极限涨点

一、本文介绍 在这篇文章中,我们将讲解如何将LSKAttention大核注意力机制应用于RT-DETR,以实现显著的性能提升。首先,我们介绍LSKAttention机制的基本原理,它主要通过将深度卷积层的2D卷积核分解为水平和垂直1D卷积核,减少了计算复杂性和内存占用。接着,我们介绍将这一…

记录留下的脚印

记录走过的脚印&#xff01;

【爬虫JS逆向-工具篇】浏览器内存漫游加密参数Hook实战教程

文章目录 1. 写在前面2. 环境搭建2. 加密定位实战 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【作者推荐】&#xff1a;对JS逆向感兴趣的朋友可以关…

数据库的备份模式(完全备份,增量备份,差异备份)

数据库的备份 备份原因 数据的丢失 数据的删除 备份目标 数据的一致性 数据的可用性 备份技术 物理备份/冷备份 直接复制数据库文件&#xff0c;适用于大型数据库环境&#xff0c;不受存储引擎的限制&#xff0c;但不能恢复到不同的MySQL版本。 常用的冷备份工具 ta…

利用iSCSI服务部署IP SAN网络存储服务

一、配置环境&#xff08;Vmware WorkStation虚拟环境&#xff09; 服务端与客户端OS&#xff1a;openEuler 22.03-LTS CPU&#xff1a;1U1C 内存&#xff1a;2G 硬盘&#xff1a;5个SCSI磁盘&#xff0c;其中一个作为系统盘&#xff0c;另外四个配置为RAID5阵列 服务器IP…

Leetcode刷题笔记题解(C++):83. 删除排序链表中的重复元素

思路&#xff1a;链表相关的问题建议就是画图去解决&#xff0c;虽然理解起来很容易&#xff0c;但就是写代码写不出来有时候&#xff0c;依次去遍历第二节点如果与前一个节点相等则跳过&#xff0c;不相等则遍历第三个节点 /*** Definition for singly-linked list.* struct …

实现Slider 滑块组件标记动态变化

实现以上效果&#xff0c;下拉框、slider滑块、按钮都在同一行&#xff0c;设置flex布局后&#xff0c;发现silider滑块最右边的标记数字一直都如下竖着显示&#xff0c;后来通过给源组件的标记区.el-slider__marks-text增加一个宽度后解决该问题。 <template><div>…

Polyspace静态检测步骤

Polyspace 是一个代码静态分析和验证的工具&#xff0c;隶属于MATLAB&#xff0c;用于检测代码中的错误和缺陷&#xff0c;包括内存泄漏、数组越界、空指针引用等。帮助开发团队提高代码质量&#xff0c;减少软件开发过程中的错误和风险。 1、打开MATLAB R2018b 2、找到Polys…

基于java,springboot和vue房屋租赁租房销售平台设计

摘要 在现代城市生活中&#xff0c;房屋租赁市场一直是一个活跃且复杂的领域。随着互联网技术的不断发展&#xff0c;基于Spring Boot和Vue的房屋租赁系统应运而生&#xff0c;旨在提供一个高效、方便、可靠的在线服务平台。该系统利用了前后端分离架构的优势&#xff0c;后端…

护眼台灯哪个品牌质量比较好?五大热门产品点评

护眼台灯作为孩子书桌上的照明神器&#xff0c;因为能起到护眼作用和很好的照明体验&#xff0c;得到了不少的认可。不过如今市场中也有很多劣质台灯&#xff0c;存在各种不足、做工差、选材廉价&#xff0c;导致光线无法起到护眼作用&#xff0c;甚至会引起近视。那么护眼台灯…

说一下 JVM 有哪些垃圾回收算法?

一、标记-清除算法 标记无用对象&#xff0c;然后进行清除回收。 标记-清除算法&#xff08;Mark-Sweep&#xff09;是一种常见的基础垃圾收集算法&#xff0c;它将垃圾收集分为两个阶段&#xff1a; 标记阶段&#xff1a;标记出可以回收的对象。清除阶段&#xff1a;回收被标…

Flutter插件开发指南02: 事件订阅 EventChannel

Flutter插件开发指南02: 事件订阅 EventChannel 视频 https://www.bilibili.com/video/BV1zj411d7k4/ 前言 上一节我们讲了 Channel 通道&#xff0c;但是如果你是卫星定位业务&#xff0c;原生端主动推消息给 Flutter 这时候就要用到 EventChannel 通道了。 本节会写一个 1~…