信息学奥赛复赛复习18-CSP-J2022-01解密-二分答案、二分找边界、二分时间复杂度、二分求最小

PDF文档回复:20241017

1 P8814 [CSP-J 2022] 解密

[题目描述]

给定一个正整数 k,有 k 次询问,每次给定三个正整数 ni,ei,di,求两个正整数 pi,qi,使 ni=pi×qi、ei×di=(pi−1)(qi−1)+1

[输入格式]

第一行一个正整数 k,表示有 k 次询问。

接下来 k 行,第 i 行三个正整数 ni,di,ei

[输出格式]

输出 k 行,每行两个正整数 pi,qi 表示答案。

为使输出统一,你应当保证 pi≤qi。

如果无解,请输出 NO

[输入输出样例]

输入 #1

10
770 77 5
633 1 211
545 1 499
683 3 227
858 3 257
723 37 13
572 26 11
867 17 17
829 3 263
528 4 109

输出 #1

2 385
NO
NO
NO
11 78
3 241
2 286
NO
NO
6 88

说明/提示

数据规模

以下记 m=n−e×d+2

保证对于 100% 的数据,1≤k≤10^5,对于任意的 1≤i≤k,1≤ni≤10^18,1≤ei×di≤ 10^18,1≤m≤ 10^9

2 相关知识点

二分答案

二分答案顾名思义,它用二分的方法枚举答案,并且枚举时判断这个答案是否可行

直接对答案进行枚举查找,接着判断答案是否合法。如果合法,就将答案二分进一步靠近,如果不合法,就接着二分缩小判断。这样就可以大大的减少时间。

二分中有时可以得可行得答案,但不是最大的,继续向右靠近,求出最大值

int ans = 1;
 int l = 1,r = 100000;//在1~100000之间的整数枚举 
 while(l <= r){
     int m = l + (r - l) / 2;
     if(check(m)){//满足 则进行向右缩小范围 看看有没有更大的 
         ans = m;//可能多次赋值 最后一定是可能的最大值 
         l = m + 1;
      }else{//不满足缩小边长 向左缩小范围 用更小边长继续尝试 
         r = m - 1;
	  } 
  }

二分找边界

//左闭右闭 while left right 最终left=right+1
while(left<=right)  left = mid + 1; right =mid-1;
//左闭右开 while left right 最终left=right
while(left<right)   left = mid + 1; right =mid;
//左开右闭 while left right 最终left=right
while(left<right)   left=mid;       right=mid-1;
//左开右开 while left right 最终left=right-1
while(left+1<right) left=mid;       right=mid;

二分查找时间复杂度

二分查找每次都缩小或扩大为原来的一半,所以也是Olog(n)

3 思路分析

基本公式推导

根据题目给出条件对基本公式进行推导

n=p * q
e * d = (p-1)*(q-1)+1
      =p*q-(p+q)+1+1
      =n-(p+q)+2
上面式子整理可得
p+q=n-e*d+2

思路1

1多次询问,每次询问暴力计算p和q

2 根据条件和推导已知p*q和p+q计算p和q的值,从1枚举到p+q的值

3 如果p*q也符合,则输出

示例程序

#include<bits/stdc++.h>
using namespace std;
int k;//k次询问
long long n,d,e,m;//n d e 3个整数 m 为p+q的值
int main(){
	cin>>k;//输入k次询问
	for(int i=0;i<k;i++){//k次询问
		cin>>n>>d>>e;//输入n d e
		m=n-e*d+2;//根据公式推导m为p+q p+q=n-e*d+2
		int p=-1;//默认p为-1
		for(int i=1;i<m;i++){//从1枚举到p+q
			if(i*(m-i)==n){//如果i为p m-i为q,判断p*q为n,满足另外一个条件 找到p 退出
				p=i;
				break;
			}
		}
		if(p!=-1){//如果找到 输出
			cout<<p<<" "<<m-p<<endl;
		}else{//找不到输出NO
			cout<<"NO"<<endl;	
		}
	}
	return 0;
}

暴力枚举可得50%分数

思路1-二分优化1

1 在思路1基础上,二分枚举,时间复杂度从n变成logn

2 使用等值比较,可能超大的2个数比较大的那个,输出时需要特殊处理

#include<bits/stdc++.h>
using namespace std;
int k;
long long n,d,e,m;
int main(){
	cin>>k;
	for(int i=0;i<k;i++){
		cin>>n>>d>>e;
		m=n-e*d+2;//p+q
		int L=1,R=m,p=-1;//1~m
		while(L<=R){//前后都是闭区间
			int mid=L+(R-L)/2;
			if(mid * (m-mid)==n){//如果相同 找到退出
				p=mid;
				break;
			}else if(mid * (m-mid)>n){
				R=mid-1;
			}else{
				L=mid+1;
			}
		}
		if(p!=-1){
			if(p>m-p){//找到的p有可能是比较大的数,如果是需要交换输出
				p=m-p;
			} 
			cout<<p<<" "<<m-p<<endl;
		}else{
			cout<<"NO"<<endl;
		}
	}
	return 0;
}

思路1-二分优化2

在上面二分的基础上,找到最小的那个数,保证二分找到的就是比较小的数

通过如下代码,如果相等也继续缩小范围找

if(mid * (m-mid)>=n){

示例代码

#include<bits/stdc++.h>
using namespace std;
int k;
long long n,d,e,m;
int main(){
	cin>>k;
	for(int i=0;i<k;i++){
		cin>>n>>d>>e;
		m=n-e*d+2;//p+q
		int L=1,R=m;
		while(L<R){
			int mid=L+(R-L)/2;
			if(mid * (m-mid)>=n){
				R=mid;
			}else{
				L=mid+1;
			}
		}
		if(R * (m-R) ==n){
			cout<<R<<" "<<m-R<<endl;
		}else{
			cout<<"NO"<<endl;
		}
	}
	return 0;
}

思路2-数学推导

数学推导

前面推导数
p+q=n-e*d+2
已知 p*q=n
根据完全平方公式
(p+q)^2=p^2+2pq+q^2  (1)
(p-q)^2=p^2-2pq+q^2  (2)
(1)-(2)得
(p+q)^2-(p-q)^2
=p^2+2pq+q^2-(p^2-2pq+q^2)
=4pq
(p-q)^2=(p+q)^2-4pq
p-q=sqrt((p+q)^2-4pq)
或
p-q=-sqrt((p+q)^2-4pq)  
我们假设p和q这2个数中,q为比较小的数,所以p-q不能为负数
p-q=sqrt((p+q)^2-4pq)   (3)
又
p+q=n-e*d+2             (4)
(3)-(4)得
2p=n−ed+2-sqrt((p+q)^2-4pq)
p=(n−ed+2-sqrt((p+q)^2-4pq))/2  (5)
(4)-(5)得
q=n-e*d+2-(n−ed+2-sqrt((p+q)^2-4pq))/2 
 =(n−ed+2+sqrt((p+q)^2-4pq))/2

示例代码

#include<bits/stdc++.h>
using namespace std;
int k;
long long n,d,e;
long long m,dt,r;//m为p+q
int main(){
	cin>>k;
	for(int i=0;i<k;i++){
		cin>>n>>d>>e;
		m=n-e*d+2;//p+q
		dt=m*m-4*n;//(p+q)^2-4pq
		r=sqrt(dt);//sqrt((p+q)^2-4pq)
		/*
		  dt为sqrt的值,不能小于0
		  r * r!=dt,dt开方为整数
		  (m-r)%2==1,(n−ed+2-sqrt((p+q)^2-4pq))/2 ,p和q必须为整数
		  上面任意条件不满足都是无解
		*/
		if(dt<0 || r * r!=dt || (m-r)%2==1){ 
			cout<<"NO"<<endl;
		}else{
			cout<<(m-r)/2<<" "<<(m+r)/2<<endl;
		}
	}
	return 0;
}

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

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

相关文章

单神经元建模:基于电导的模型[神经元结构、静息电位和等效电路]

文章目录 神经元结构、静息电位和等效电路神经元结构静息电位能斯特方程1. **描述浓度比的非线性关系**&#xff1a;2. **化学势与电势的关系**&#xff1a;3. **对称性**&#xff1a;4. **热力学与平衡**&#xff1a;总结&#xff1a; GHK方程Nernst方程和GHK方程的对比 等效电…

自动化检查网页的TDK,python+selenium自动化测试web的网页源代码中的title,Description,Keywords

首先&#xff0c;TDK是什么&#xff1f;对于新手小白来说&#xff0c;可能是懵逼的&#xff0c;所以这里给出一个官方的解说‌网页的TDK是指标题&#xff08;Title&#xff09;、描述&#xff08;Description&#xff09;和关键词&#xff08;Keywords&#xff09;的集合‌。这…

vue3播放m3u8格式hls监控流

1. 摄像头的hls监控流不同于普通m3u8的视频&#xff0c;video标签&#xff0c;iframe&#xff0c;videojs&#xff0c;vue-video-player无法解析 2. 解决办法 更换LivePlayer插件 官网https://www.liveqing.com/docs/manuals/LivePlayer.html#%E5%B1%9E%E6%80%A7-property 3…

Java项目-基于Springboot的招生管理系统项目(源码+说明).zip

作者&#xff1a;计算机学长阿伟 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、ElementUI等&#xff0c;“文末源码”。 开发运行环境 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI工具&#xff1a;IDEA/…

Tkinter -- python GUI学习与使用

前言 python GUI 目前pythonGUI有很多&#xff0c;哪一个最好&#xff1f; 先说说我选择的思路&#xff0c;我的目的是开发一个易用的软件&#xff0c;最重要的是稳定&#xff0c;并且碰到问题能够解决&#xff0c;因此&#xff0c;我的目标很明确&#xff0c;有比较大的用户群…

cefsharp79.1.360(Chromium 79.0.3945.130)支持H264视频播放-PDF预览 老版本回顾系列体验

一、关于此版本 版本:Cef 79.1.36/CefSharp 79.1.360/Chromium 79.0.3945.130/支持H264/支持PDF预览 支持PDF预览和H264推荐版本 63/79/84/88/100/111/125 运行环境需要 visual c++ 2015不支持xp/vista/2003/2008默认不支持h264(版权问题)支持打印预览 print preview已知问题…

【计算机网络原理】GBN,SR,TCP区别以及案例介绍

概念介绍 GBN、SR和TCP协议的主要区别在于它们的重传机制、确认方式以及缓存机制的不同。‌ GBN&#xff08;Go-Back-N&#xff09;协议在数据传输中&#xff0c;如果某个报文段没有被正确接收&#xff0c;那么从这个报文段到后面的所有报文段都需要重新发送。GBN采用累计应答…

UI自动化测试 —— web端元素获取元素等待实践!

前言 Web UI自动化测试是一种软件测试方法&#xff0c;通过模拟用户行为&#xff0c;自动执行Web界面的各种操作&#xff0c;并验证操作结果是否符合预期&#xff0c;从而提高测试效率和准确性。 目的&#xff1a; 确保Web应用程序的界面在不同环境(如不同浏览器、操作系统)下…

每日OJ题_牛客_[NOIP2001]装箱问题_01背包_C++_Java

目录 牛客_[NOIP2001]装箱问题_01背包 题目解析 C代码 Java代码 牛客_[NOIP2001]装箱问题_01背包 [NOIP2001]装箱问题 (nowcoder.com) 描述&#xff1a; 有一个箱子容量为V&#xff08;正整数&#xff0c;0 ≤ V ≤ 20000&#xff09;&#xff0c;同时有n个物品&…

面向对象进阶(上)(JAVA笔记第二十二期)

p.s.这是萌新自己自学总结的笔记&#xff0c;如果想学习得更透彻的话还是请去看大佬的讲解 目录 static修饰符静态变量静态方法 工具类工具类的使用例子第一题第二题 static注意事项继承关系建立继承关系的格式继承的好处及使用场景继承的特点继承体系的设计继承中类的三大要素…

redis集群介绍

Redis集群是一种分布式存储系统&#xff0c;它通过将数据分散存储在多个Redis节点上来实现可扩展性和高可用性。每个节点都是一个独立的Redis服务器实例&#xff0c;它们通过网络相互连接&#xff0c;共同协作以提供数据服务。 在Redis集群中&#xff0c;数据被划分为多个槽&am…

巧用这4款免费视频剪辑软件,帮你释放无限的创意。

可以免费使用的视频剪辑软件对于普通创作者而言还是比较重要的。因为越来越多的人渴望通过视频来表达自己的创意、分享生活点滴以及传达各种信息。专业的软件价格贵&#xff0c;操作复杂。简单免费的工具才是大多数人的选择&#xff0c;所以我要给大家介绍几个好用且免费的剪辑…

3D Slicer 教程三 ---- 坐标系

上篇提到3D Slicer 教程二 ---- 数据集-CSDN博客 3d slicer的坐标系与大多数医学影像软件使用LPS&#xff08;左、后、上&#xff09;坐标系统不太一样, 今天就仔细介绍一下坐标系的区别,复盘一下在影像处理中遇到的坐标问题(集中在坐标处理相关的,图像插值,图像处理, 定位线,翻…

服务器软件之Tomcat

服务器软件之Tomcat 服务器软件之Tomcat 服务器软件之Tomcat一、什么是Tomcat二、安装Tomcat1、前提&#xff1a;2、下载3、解压下载的tomcat4、tomcat启动常见错误4.1、tomcat8.0 startup报错java.util.logging.ErrorManager: 44.2、java.lang.UnsatisfiedLinkError 三、Tomca…

Ansible概述

目录 一、ansible简介 二、absible的特点 三、ansible的工作原理以及流程 四、ansible环境安装部署 五、ansible命令行模块 六、inventory 主机清单 一、ansible简介 Ansible是一个基于Python开发的配置管理和应用部署工具&#xff0c;现在也在自动化管理领域大放异彩。…

应用层——电子邮件、MIME、简单网络管理协议SNMP

电子邮件 电子邮件系统采用三个主要构件组成&#xff1a;用户代理、邮件服务器、电子邮件所需的协议 我们可以简单的认为邮件服务器中有很多邮箱&#xff0c;还有用来缓存再转发邮件的缓存&#xff0c;发送方使用用户代理通过邮件发送协议。例如SMTP将邮件发送给发送方。 邮件服…

基于MATLAB的混沌序列图像加密程序

设计目的 图像信息生动形象&#xff0c;它已成为人类表达信息的重要手段之一&#xff0c;网络上的图像数据很多是要求发送方和接受都要进行加密通信&#xff0c;信息的安全与保密显得尤为重要&#xff0c;因此我想运用异或运算将数据进行隐藏&#xff0c;连续使用同一数据对图…

排序04 视频播放建模

视频播放时长 用p拟合y&#xff0c;t是用户的实际观看时长&#xff0c;用y和p熵作为损失函数&#xff0c;使得p接近y。 输出z,对z做sigmoid变换。 exp(z)可以视为对播放时长的预估 视频完播 回归方法 二元分类方法 调整&#xff1a;预估完播率不能直接使用

预置持久化应用或者常驻应用会导致自升级不了android:persistent=”true”属性

1.错误打印&#xff1a; 2.问题原因&#xff1a; Android系统策略限制&#xff0c;持久化&system 不能自升级 3.持久化应用通常会在AndroidManifest.xml上下文有没配置android:persistent”true”属性 4.解决方案&#xff1a; 1.应用去掉android:persistent”true”属性…

【基于docker的深度学习训练环境】关键步骤记录

最近给公司搭建了一个小型的深度学习环境&#xff0c;实现了多人通过SSH对GPU资源的利用&#xff0c;下面对一些关键架构和易用性部分进行记录。 一、整体软硬件框架 1、硬件配置&#xff0c;采用的双GPU的方案&#xff0c;两块消费级显卡。 2、应用层架构 宿主机系统为ubunt…