两道 杂题

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

说明/提示

【评测用例规模与约定】

  • 对于 30% 的评测用例,n≤500,ai​≤1000;
  • 对于 50% 的评测用例,n≤5000,ai​≤10^6;
  • 对于所有评测用例,1≤n≤10^5,1≤ai​≤10^9。

蓝桥杯 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

你可能感兴趣的:(算法,c++,数据结构)