Arithmetic Progression 题解(随机数使用)
思路:
本题的意思:求首项与公差。
第一部分:观察一下,题目的第二类操作(比某数大,有单调性)明显是要我们用二分(或者我觉得其实随机数也行,根据随机数来不断缩小范围,但是这题练二分)求最大值,大概要操作Log2 1e9= 29.897353约30次。
float f1=3e2;//3*(10^2);
f1结果为300;
float f1 =3e-2;//3*(0.1^2);
f2结果为0.03;
第二部分:求公差,由于一开始已经有n,有了公差和最大值就有了首项,这时就要用到第一个操作。
对于任意三个数,我们有:
an=a1+(n-1)*d am=a1+(m-1)*d ak=a1+(k-1)*d
两两相减去,我们可以得到关于d和n、m、k的关系式,这个时候对这些差求最小公倍数,后面不停地进行询问,一直问个多次,然后最后得到k。(把前面·30个都问一遍会被卡数据,用随机数会更好一些)
随机数
C++ 库有一个名为 rand() 的函数,每次调用该函数都将返回一个非负整数。要使用 rand() 函数,必须在程序中包含 头文件。以下是其用法示例:
randomNum = rand();
该算法需要一个起始值,称为种子,以生成数字。如果没有给出一个种子,那么它将在每次运行时产生相同的数字流。
在 rand 被调用之前,srand 函数要先被调用,并且 srand 在整个程序中仅被调用一次
变量 seed 被声明为 unsigned 无符号类型。这个数据类型只保存非负整数。这是 srand 函数在调用时期望接收的数据类型
有时程序需要一个特定范围内的随机数。要将随机数的范围限制在 1 和某个最大值 max 之间的整数,可以使用以下公式:
number = rand() % max + 1;
time 函数返回从 1970 年 1 月 1 日午夜开始到现在逝去的秒数,因此每次运行程序时,它都将提供不同的种子值。下面程序演示了 time 函数的用法。请注意,在调用它时必须给它传递一个参数 0。同时程序中包含一个新的头文件 ctime,此头文件是使用 time 函数所必需的。
这个想法可以扩展到任意范围内的随机数,其通用公式如下:
number = (rand()%(maxValue - minValue +1)) + minValue;
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<ctime>
using namespace std;
typedef long long ll;
ll lef=0,righ=1e9,n,mid,tot=0;
ll num[100],top=0;
bool check(ll k){bool f=0;printf("> %lld\n",k);fflush(stdout);cin>>f;return f;
}
ll gcd(ll a,ll b){(辗转相除法求最大公倍数,如果b比a大,下面自然会调转顺序)if(a%b==0)return b;else return gcd(b,a%b);
}
int main(){cin>>n;srand(time(0));(这里有点迷)ll i=1,m;while(lef<righ){(找最大值)tot++;mid=(lef+righ)/2;if(check(mid))lef=mid+1;else righ=mid;}if(n<60-tot)while(i<=n){(如果该数比较小的话,就直接读入,不用随机数了)printf("? %lld\n",i);i++;fflush(stdout);top++;cin>>m;num[top]=m;}elsewhile(tot<60){i=rand()%(n-i+1)+i;(让随机数逐渐递增,在i到n的区间内进行选择)printf("? %lld\n",i);tot++;fflush(stdout);cin>>m;top++;num[top]=m;}m=righ-num[1];(两两差求最大公倍数,可以得到共同的公差)for(i=1;i<=top;i++)if(righ-num[i]>0&&m>0)m=gcd(m,righ-num[i]);printf("! %lld %lld\n",righ-m*(n-1),m);return 0;
}
结论:这题其实思路并不难想,主要是实现的时候有些细节要注意,例如说当n比较小的时候直接输入,然后的话学一学随机数算法(有种赶脚就是这个应该经常会在交互题中用到)
Arithmetic Progression 题解(随机数使用)相关推荐
- CF1673DLost Arithmetic Progression 题解
a,b公差的最小公倍数就是c的公差 判断0的情况比较多,但是都比较trival 1. 区间c未完全属于区间a 2.公差不能除尽 3.首项之差不能除尽a的公差,简而言之就是对不上 判断-1的情况我考场的 ...
- 奇思妙想构造题 ARC145 D - Non Arithmetic Progression Set
Non Arithmetic Progression Set 大意: 给定m,n 要求构造一个序列: 长度=n,元素和=m,任意三个元素无法构成等差数列,|a[i]|<=1e7 思路: 一开始这 ...
- Almost Arithmetic Progression
time limit per test 1 second memory limit per test 256 megabytes input standard input output standar ...
- Almost Arithmetic Progression(CF-978D)
Problem Description Polycarp likes arithmetic progressions. A sequence [a1,a2,-,an] is called an ari ...
- cf----2019-10-20(Consecutive Subsequence,Almost Arithmetic Progression,Mentors)
一场游戏一场空,最终 最初都由我掌控,好像一身从容,不曾有狼狈伤痛,可深夜一个人该如何相拥? You are given an integer array of length nn. You have ...
- HDU5142 NPY and arithmetic progression BestCoder Round #23 1002
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5143 解题思路:BestCoder官方题解: 可以发现等差数列只有(123,234,1234和长度&g ...
- PAT(甲级)2021年春季考试 7-1 Arithmetic Progression of Primes
思路:用筛除法打素数表(与之相对的是枚举加逐个判断)是降低时间复杂度的第一个点,第二个点是运用上数学技巧,给定了等差数列的范围(2-MAX),给定了个数,那么最大的等差是可以求出的.循环的第一层从最大 ...
- Codeforces Round #224 (Div. 2): C. Arithmetic Progression(模拟)
题意: 给你n个数字,你需要再添加一个数字,使得最后所有数字排序之后任意相邻两个数之差全部相等,问可以添加多少种不同的数字 思路: 一看就是水题但是情况不少,没了 例如所有数字全部相等,只有两个数字, ...
- 2021牛客多校第二场 A——Arithmetic Progression
题目大意 给你一个长度为 nnn 的数列 aaa ,数列中每个元素都不一样,问你存在多少个区间,这些区间内的数排序后是一个等差数列 解题思路 对于一个区间,如果这个区间内的数排序后的元素可以构成一个等 ...
最新文章
- 基于Python下的Apriltag检测
- 12月21 vs2012 数据类型
- springBoot使用PageHelper当超过最大页数后仍然返回数据
- MongoDB Sharding分片配置
- 利用linux的df和du命令查看文件和目录的内存占用
- Linux运维必备的40个命令总结(值得收藏)
- Java 编写程序 创建一个游戏【5、6两章的内容】【第5章】
- Java对象分配原理
- 消息队列原理和应用场景总结
- 交换机串行损耗解决之预加重与均衡对比
- 地图瓦片坐标系定义及计算原理
- 【服务器数据恢复】IBM服务器RAID控制器出错的数据恢复案例
- ps裁剪和裁切的区别_PS图片的裁剪和裁切的含义和应用
- 第九批游戏版号下发 巨人网络一游戏获版号
- FC6下chm文件阅读器chmsee的安装
- 【svn】 如何在Linux服务器上添加svn账户的教程
- 荷兰DELTA电源维修SM66-AR-110德尔塔电源
- 数仓的基本概念【精】
- 2022年全新数据仓库面试总结大全
- JDBC学习笔记(1)---B站尚硅谷宋红康