20240401学习总结

1、P8682 [蓝桥杯 2019 省 B] 等差数列

一个找最大公约数的题,复习一下找最大公约数

int gcd(int a,int b){
 return b?gcd(a,a%b):a);
}

b==0时候返回a,否则递归

思路:首先对数组进行排序,然后中出两两元素之间差的最大公约数,因为两两元素之间的差一定是公差的整数倍,要想数组最短就要公差最大。找出最大公约数之后,如果最大公约数等于0,则数组长度等于n,否则等于(最大数-最小数)/最大公约数+1

#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5+10;
long long a[N];
int n;
int gcd(int a,int b){
   return b?gcd(b,a%b):a;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	  scanf("%lld",&a[i]);
	sort(a+1,a+1+n);
	int pp=a[2]-a[1];
	for(int i=3;i<=n;i++)
	  pp=gcd(pp,a[i]-a[i-1]);
	long long count=0;
	if(pp==0)  count=n;
	else  count=(a[n]-a[1])/pp+1;
	cout<<count<<endl;
	return 0;
}

2、P8651 [蓝桥杯 2017 省 B] 日期问题

这个题目比较繁琐,

小明正在整理一批历史文献。这些历史文献中出现了很多日期。

小明知道这些日期都在1960年1月1日至2059年12月31日。

令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。

更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。

比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。

给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?

输入格式

一个日期,格式是”AA/BB/CC”。

即每个’/’隔开的部分由两个 0-9 之间的数字(不一定相同)组成。

输出格式

输出若干个不相同的日期,每个日期一行,格式是”yyyy-MM-dd”。

多个日期按从早到晚排列。

思路:首先对每一种情况需要判断年月日日否符合规范,这里需要复习一下判断闰年的表示方式

//判断闰年
if(x%4==0&&x%100!=0||x%400==0)

之后就是对每一种情况进行检查,比较讨厌的一点是要按照从小到大的顺序进行排列,所以选择用结构体进行排列,之后对于相同的情况进行特判。y总采用的方式是列举日期。

#include<iostream>
#include<algorithm>
const int N=10;
using namespace std;
struct date{
	int year;
	int month;
	int day; 
}d[N];
bool cmp(date a,date b){
	if(a.year !=b.year )  return a.year <b.year ;
	else if(a.month !=b.month )  return a.month <b.month ;
	else if(a.day !=b.day )  return a.day <b.day ;
}
int check(int x,int y,int z){
	if(y<1||y>12)  return 0;
	if(y==1||y==3||y==5||y==7||y==8
	||y==10||y==12){
		if(z<1||z>31)  return 0;
	}
	if(y==4||y==6||y==9||y==11){
		if(z<1||z>30)  return 0;
	}
	if(y==2){
		if(x%4==0&&x%100!=0||x%400==0){
			if(z<1||z>29) return 0;
		} 
		else if(z<1||z>28)  return 0;
	}
	return 1;
}
int main(){
	int a,b,c,i=1;
	scanf("%02d/%02d/%02d",&a,&b,&c);
	if(a>=60){
		int t=a+1900;
		if(check(t,b,c))  
		   {
		   	d[i].year=t;
		   	d[i].month=b;
		   	d[i].day =c;
		   	i++;
		   }
		  //printf("%d-%02d-%02d\n",t,b,c);
	}
	else if(a<=59){
		int t=a+2000;
		if(check(t,b,c))
		  //printf("%d-%02d-%02d\n",t,b,c);
		  {
		   	d[i].year=t;
		   	d[i].month=b;
		   	d[i].day =c;
		   	i++;
		   }
	}
	if(c>=60){
		int t=c+1900;
	    if(check(t,a,b))
		  //printf("%d-%02d-%02d\n",t,a,b);
		  {
		   	d[i].year=t;
		   	d[i].month=a;
		   	d[i].day =b;
		   	i++;
		   }
		if(check(t,b,a))
		  //printf("%d-%02d-%02d\n",t,b,a);
		  {
		   	d[i].year=t;
		   	d[i].month=b;
		   	d[i].day =a;
		   	i++;
		   }
	}
	else if(c<=59){
		int t=c+2000;
		if(check(t,a,b))
		  //printf("%d-%02d-%02d\n",t,a,b);
		  {
		   	d[i].year=t;
		   	d[i].month=a;
		   	d[i].day =b;
		   	i++;
		   }
		if(check(t,b,a))
		 // printf("%d-%02d-%02d\n",t,b,a);
		 {
		   	d[i].year=t;
		   	d[i].month=b;
		   	d[i].day =a;
		   	i++;
		   }
	}
	sort(d+1,d+1+i-1,cmp);
	
	for(int j=1;j<i;j++){
		bool flag=1;
		if(d[j].year ==d[j-1].year &&d[j].month ==d[j-1].month &&d[j].day ==d[j-1].day )  flag=0;  
	    if(flag==1)
		 printf("%d-%02d-%02d\n",d[j].year ,d[j].month ,d[j].day );
	}
	return 0;
}

3、P8635 [蓝桥杯 2016 省 AB] 四平方和

四平方和定理,又称为拉格朗日定理:

每个正整数都可以表示为至多 44 个正整数的平方和。

如果把 00 包括进去,就正好可以表示为 44 个数的平方和。

比如:

5=02+02+12+225=02+02+12+22。

7=12+12+12+227=12+12+12+22。

对于一个给定的正整数,可能存在多种平方和的表示法。

要求你对 44 个数排序使得 0≤a≤b≤c≤d。

并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法。

思路:暴力搜索

#include<iostream>
#include<cmath>
using namespace std;
int n,a,b,c,d;
int check(int x,int y,int z,int s)
{
	return x*x+y*y+z*z+s*s; 
}
int main(){
	cin>>n;
	for(int i=0;;i++){
		if(check(i,i,i,i)>n)  break;
		for(int j=i;;j++){
			if(check(j,j,j,j)>n)  break;
			for(int k=j;;k++){
				if(check(k,k,k,k)>n)  break;
				int t=sqrt(n-i*i-j*j-k*k);
				if(check(i,j,k,t)==n) 
				  {
				  	cout<<i<<" "<<j<<" "<<k<<" "<<t<<endl;
					 return 0;
				  }
			}
		}
	}
	return 0;
}

4、P8754 [蓝桥杯 2021 省 AB2] 完全平方数 

一个整数 a是一个完全平方数,是指它是某一个整数的平方,即存在一个整数 b,使得 a=b^2。

给定一个正整数 n,请找到最小的正整数 x,使得它们的乘积是一个完全平方数。

输入格式

输入一行包含一个正整数 n。

输出格式

输出找到的最小的正整数 x。

直接暴力会超时,这里有一个小知识点:一个完全平方数一定可以分成若干个质因子相乘,并且每个质因子的次数一定是偶数次(因为完全平方嘛)所以这个题目如果n*x是一个完全平方,那么县看n里面质因子次数,如果是偶数次的就跳过,如果是奇数次的就需要再乘上一个变成偶数次,也就是说x等于奇数次的质因子相乘

这里有一个求质因子的板子(找到一个好东西acwing里面y总有总结很多的基本算法模版,比赛之前要好好看一下)

#include<iostream>
using namespace std;
long long n,x=1;
int main(){
	scanf("%lld",&n);
	for(long long i=2;i*i<=n;i++){
		if(n%i==0){
			int t=0;
			while(n%i==0){
				n=n/i;
				t++;
			}
			if(t%2==1)  x=x*i;
		}
	}
	if(n>1) x=x*n; //最后还要看一下是不是除尽了
	printf("%lld\n",x);
	return 0;
}

5、P8707 [蓝桥杯 2020 省 AB1] 走方格

在平面上有一些二维的点阵。

这些点的编号就像二维数组的编号一样,从上到下依次为第 11 至第 n� 行,从左到右依次为第 11 至第 m 列,每一个点可以用行号和列号来表示。

现在有个人站在第 11 行第 11 列,要走到第 n� 行第 m� 列。

只能向右或者向下走。

注意,如果行号和列数都是偶数,不能走入这一格中。

问有多少种方案。

思路:动态规划,当i==n&&j==m时 f=1  当是偶数时 f=0  其余情况f[i][j]=f[i-1][j]+f[i][j-1]

#include<iostream>
using namespace std;
long long n,m;
long long f[189][189];
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(i==1&&j==1)
			  f[i][j]=1;
			else if(i%2==1||j%2==1) 
			 f[i][j]=f[i-1][j]+f[i][j-1];
		}
	}
	cout<<f[n][m]<<endl;
	return 0;
} 

  • 24
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值