俱乐部训练题1

先排序,然后求出输入的数列各项的差值数列,求这个差值数列的各项最大公因数即可,这道题需要注意的地方是它的特殊情况,当这对数里有两个相同的数的时候,这个数列是常数列,那么一开始在过程中用到的除以公差的运算就不能再用了,

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

int p(long f,long g)
{
	long tem;
	if(f>g)
	{
		tem=f;
		f=g;
		g=tem;
	}
	if(f==g) return f;

	do {
	g=g-f;
	if(f>g)
	{
		tem=f;
		f=g;
		g=tem;
	}
	} while(g%f!=0);
	return f;
	
}
int main()
{
	long n,a[100006],i,b[100006],c,d;
	cin>>n;
	for(i=0;i<n;i++)
	cin>>a[i];
	sort(a,a+n);
	d=a[0];
	for(i=0;i<n;i++)
	{

	a[i]=a[i]-d;
    
    }
for(i=0;i<n-1;i++)
	{
    if(a[i]==a[i+1])
    {
	
	cout<<n;
    return 0;
}
    }

    c=a[1];
    for(i=2;i<n;i++)
    {
    	c=p(c,a[i]-a[i-1]);
	}
   
	cout<<(a[n-1]/c)+1;
}

采用了快速幂运算,这里用上了递归的方法,

#include<iostream>
#include<cmath>
using namespace std;
long i,e[6553666],s;
long d(long a,long b,long p)
{

	if(b%2==0)
	{
		a=(a*a)%p;
		b=b/2;
			
			s=a;
		d(a,b,p);
		a=s;
		return a;
	}
	else
	{
		i++;
		e[i]=a;
		if(b!=1)
		{
		
		a=(a*a)%p;
		b=(b-1)/2;
			
			s=a;
		d(a,b,p);
		a=s;
	            
		a=(a*e[i])%p;
     }
     a=a%p;
		i--;

}
s=a;
}
int main()
{
	long a,b,p,g,h; 
	i=0;	
	cin>>a>>b>>p;
	g=a;
	h=b;
    d(a,b,p);

	cout<<g<<'^'<<h<<" "<<"mod"<<" "<<p<<'='<<s;
}

数据量较大,尝试减少不必要的反复运行过程,对数列排序可以做到这一点,运用了结构体的形式,在排序完之后可以再回到原来的顺序,因为最后结果要按照输入的顺序输出

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
	long a[1000006],k[100005],c,d,i,j;
	struct fuck
	{
		long e;
		long f;
		long g;
	};
	fuck b[100005];
	bool cmpe(fuck x,fuck y)
	{
		return x.e<y.e;
	}
	bool cmpf(fuck x,fuck y)
	{
		return x.f<y.f;
	}
int main()
{

	cin>>c>>d;
	
	for(i=0;i<c;i++) cin>>a[i];
	for(i=0;i<d;i++) {
	cin>>b[i].e;
	b[i].f=i;
}
	sort(b,b+d,cmpe);
	j=0;
	for(i=0;i<d-1;i++)
	{
		if(b[i].e<a[j]) {
		b[i].g=-1;
		continue;
	}

		while(j<c&&b[i].e>a[j])
		{
		
		j++;
	}
		if(b[i].e==a[j]) b[i].g=j+1;
		else b[i].g=-1;
		
	}
i=d-1;
	if(b[i].e<a[j]) {
		b[i].g=-1;
		return 0;
	}

		while(j<c&&b[i].e>a[j])
		{
		
		j++;
	}
		if(b[i].e==a[j]) b[i].g=j+1;
		else b[i].g=-1;	
		sort(b,b+d,cmpf);
		for(i=0;i<d;i++)
		{
			cout<<b[i].g<<' ';
		}
}

这个题我最后还是没有做出来,时间超了三倍,怎么改也超时,下面的这个是转载的

#include <bits/stdc++.h>
using namespace std;
int n,m;
int ans=-1;
int a[1000005];
bool check(int x){   //答案是否满足,满足返回1,反之返回0
    int now = 1, num = 1;
    for (int i = 2; i <= n; i++){
        if (a[i]-a[now]>=x){
            now=i;
            num++;
        }
    }
    return num>=m;
}
void merge(int l,int r){
	if(r-l<0) return;    //边界
	int mid=l+(r-l>>1);    //这样处理防止溢出
	if(check(mid)){   //如果满足,我们记录当前最大值,然后往左区间寻找答案
		merge(mid+1,r);
		ans=max(ans,mid);
	}
	else{  //如果不满足,就往右区间寻找
		merge(l,mid-1);
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	sort(a+1,a+n+1);  //注意,要排序处理。
	merge(1,(2<<30));
	printf("%d",ans);
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值