1、最少刷题数
小蓝老师教的编程课有 N 名学生,编号依次是 1...N。
第 i 号学生这学期刷题的数量是Ai。
对于每一名学生,请你计算他至少还要再刷多少道题,才能使得全班刷题比他多的学生数不超过刷题比他少的学生数。
第一行包含一个正整数 N。
第二行包含 N 个整数:A1,A2,A3,...,AN。
输出 N 个整数,依次表示第 1...N号学生分别至少还要再刷多少道题。
对于 30%的数据,1≤N≤1000,0≤Ai≤1000。
对于 100% 的数据,1≤N≤100000,0≤Ai≤100000。
5
12 10 15 20 6
0 3 0 0 7
因为数据会有相等的,所以使用二分。
#include
using namespace std;
#define int long long
#define fp(i,a,b) for(int i=a;i<=b;++i)
const int N=1e6+10;
const int mod=1e9+7;
const double eps=1e-5;
typedef double db;
int n;
int mmax;
int a[N],b[N];
bool check(int x,int y)
{
int st=-1;
int ed=-1;
int l=1,r=n;
while(l>1;
if(b[mid]>=x)r=mid;
else l=mid+1;
}
st=l;
l=1,r=n;
while(l>1;
if(b[mid]<=x)l=mid;
else r=mid-1;
}
ed=l;
int lcnt=st-1;
int rcnt=n-ed;
if(y>n;
fp(i,1,n)cin>>a[i],b[i]=a[i],mmax=max(mmax,a[i]);
sort(b+1,b+1+n);
for(int i=1;i<=n;i++)
{
int l=a[i],r=mmax;
while(l>1;
if(check(mid,a[i]))r=mid;
else l=mid+1;
}
cout<
2、最大公约数
给定一个数组,每次操作可以选择数组中任意两个相邻的元素 x, y并将其中的一个元素替换为gcd(x,y),其中 gcd(x,y) 表示 x 和 y 的最大公约数。请问最少需要多少次操作才能让整个数组只含 1。
输入的第一行包含一个整数 n,表示数组长度。
第二行包含 n 个整数 a1,a2,…,an,相邻两个整数之间用一个空格分隔。
输出一行包含一个整数,表示最少操作次数。如果无论怎么操作都无法满足要求,输出 −1。
输入 #1
3 4 6 9
输出 #1
4
【评测用例规模与约定】
蓝桥杯 2022 国赛 A 组 D 题。
首先要使整个数列为 1,必须要先有一个位置的值为 1,再逐步拓展。问题就转化为拼出一个 1 的最少步数。又由于题目要求只能用相邻两数来进行gcd,所以要拼出 1 个 1 必须是一个区间内的数进行 gcd。维护一个区间 gcd,套个双指针就可以了。这里用的是 st 表,时间复杂度O(nlogn+n)。
#include
using namespace std;
#define int long long
#define fp(i,a,b) for(int i=a;i<=b;++i)
const int N=1e5+10;
const int mod=1e9+7;
const double eps=1e-5;
typedef double db;
int Max[N][25];
int lg[N];
int n;
int a[N];
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
int query(int l,int r)
{
int k=lg[r-l+1];
return gcd(Max[l][k],Max[r-(1<>n;
int cnt=0;
fp(i,1,n)
{
cin>>Max[i][0];
a[i]=Max[i][0];
if(a[i]==1)cnt++;
}
for (int i = 2; i <= n; i++) lg[i] = lg[i >> 1] + 1;
for(int j=1;j<=lg[n];j++)
{
for(int i=1;i+(1<1)
{
cout<<-1;
return 0;
}
int ans=n;
for (int l=1,r=1;r<=n;r++) {
while (l