蓝桥杯C/C++第三次培训

1.日期处理

在蓝桥杯比赛中日期处理是经常考的题目是难点也是重点,但做出题目的方法有很多,Excel表格熟练的同学可以用Excel表格做出来,但用Excel表格做会花费很长时间才能做出来,而且不一定能作对,感觉很不划算,今天我们用C语言一起来解决它
1.1预备知识
     1.1.1swap函数
swap函数是C++中algorithm头文件下的函数,其作用是交换两个数的值
swap(x,y)用来交换x,y,的值
代码示例

#include <stdio.h>
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
    
    
    int x,y;
    cin>>x>>y;
    swap(x,y);
    cout<<x<<" "<<y<<endl;
   return 0;
}

一个n位整数x取后m位数组成的数:x%pow(10,m),pow(a,b)表示a的b次方在math.c里面,去前n-m位数:x/pow(10,n-m)
1.2数据的多组输入
与单组数据输入测试相比多组数据测试一次能运行所有数据,并且结果都是正确的
1.2.1while…EOF
在C语言中,或更精确地说成C标准函数库中表示文件结束符(end of file)。在while循环中以EOF作为文件结束标志,这种以EOF作为文件结束标志的文件,必须是文本文件。在文本文件中,数据都是以字符的ASCII代码值的形式存放。我们知道,ASCII代码值的范围是0~127,不可能出现-1,因此可以用EOF作为文件结束标志。可以用于多组输入

#include <stdio.h>
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
int a[100010];
int main()
{
    
    
	int n;
	while(scanf("%d",&n)!=EOF)
	{
    
    
		printf("%d",n);
	}
	return 0;
}

在这"scanf("%d",&n) != EOF"相当于"scanf("%d",&n) != EOF",或"~scanf("%d",&n)",或"scanf("%d",&n) == 1 " 。scanf的返回值由后面的参数决定
1.2.2while(t–)
其中t为测试的次数
1.2.3while(cin>>a)
用于检测IO流的输入流是否正常,正常返回true,否则返回false

#include <stdio.h>
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
int a[100010];
int main()
{
    
    
	int a;
	while(cin>>a)
	{
    
    
	cout<<a<<endl;
	}
	return 0;
}

1.3取两个日期之间相差的天数
     思路解析
设两个日期time1、time2,相差日期ans,time1在前,time2在后,具体处理:每当ans加1,time1加1,直到time1等于time2。
注意问题:

  1. 平年和闰年及判断
  2. 当time1加一后的天数d等于当前月份天数加一时,d置为1,月份m加1,当m等于13时,m置为1,年份y加1

参考代码

#include <stdio.h>
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
int day[13][2]={
    
    0,0,31,31,28,29,31,31,30,30,31,31,30,30,31,31,31,31,30,30,31,31,30,30,31,31};//保存每月的天数
bool judge(int x)//平年、闰年判断
{
    
    
	if((x%4==0&&x%100!=0)||x%400==0)
	return true;
	return false;
}
int main()
{
    
    
   int year1,year2,y1,y2,m1,m2,d1,d2;
   while(scanf("%d %d",&year1,&year2)!=EOF)//多组输入
   {
    
    
   	if(year1>year2)//将日期设为year1<year2
   	{
    
    
   		swap(year1,year2);
	   }
	   //分别取年、月、日
   	 y1=year1/10000;
   	 m1=year1%10000/100;
   	 d1=year1%100;
   	 y2=year2/10000;
   	 m2=year2%10000/100;
   	 d2=year2%100;
   	 int ans=0;//设置相差天数为0,例2020/1/1与2020/1/2相差一天
   	 while(y1<y2||m1<m2||d1<d2)
		{
    
    
			ans++;//相差天数加1
			d1++;
			if(d1==day[m1][judge(y1)]+1)//当d1比当前月份天数大一天(天数满足当前天数)
			{
    
    
				d1=1;//天置为1
				m1++;//月份加1
			 } 
			 if(m1==13)//当过了12月
			 {
    
    
			 	m1=1;//月份置为1
			 	y1++;//年份加1
			 }
		 }
		 cout<<ans<<endl; 
   }
}

2进制转换

在生活经常使用的是10进制,而计算机当中经常使用二进制,另外还有八进制,十六进制。他们之间的进制转换‘必须掌握
2.1将p进制x转为十进制y
在这里插入图片描述
将其转为10进制y
在这里插入图片描述
代码演示

#include <stdio.h>
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
    
    
   int p,x;//p进制数x 
   cin>>x>>p;
   int ans=0;//转化为十进制的结果 
   int y=1;//每位数乘的p的次方项p^0,p^1,p^2...p^n-1 
   while(x)
   {
    
    
   	  int a=x%10;//去x的每一位数 
		 x=x/10; 
		 ans+=a*y;
		 y=y*p; 
	} 
	cout<<ans<<endl;
   return 0;
}

2.2将十进制的x转为p进制的y
通常采用“除基取余法”,所说的基是指要转换的进制p,除基取余的意思是每次将待转数除以p,然后将所的得到的数最为地位存储,而商则继续除以p并进行上面的操作,最后当商为0时,将所有从低到高的输出就可以得到z。
代码演示

#include <stdio.h>
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <stack>
using namespace std;
int main()
{
    
    
  int x,p;//十进制x,以及要转换的进制p
  cin>>x>>p;
  stack <int> ans;
  do //do..while循环排除x为0的情况 
  {
    
    
  	int m=x%p;//求基取余
	  x=x/p;
	  ans.push(m);//将每一位结果存入栈中 
   }while(x);
   while(!ans.empty())//将结果输出 
   {
    
    
   	cout<<ans.top();
   	ans.pop();
	} 
   return 0;
}

2.3将p进制x转为n进制y
思路:先将p进制x转化为10进制的z,在将10进制的z转为n进制的y

3 字符串

字符串是常见的题型也是常考的题型,为了在蓝桥杯中那个好成绩,字符串的题目必须都会,常见的有回文字符串,字符串排序,以及字符串搜索和最长回文字串
3.1回文字符串
像"a",“aba”,"abba"这种从前往后和从后往前读是一样的字符串为回文字符串
常用知识点:reverse函数和字符串比较
代码演示:

#include <stdio.h>
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <stack>
using namespace std;
int main()
{
    
    
 string s;
 cin>>s;
 string s1=s;
 reverse(s1.begin(),s1.end());
 if(s1==s)
 cout<<"Yes";
 else
 cout<<"No";
  return 0;
}

3.2字符串排序
题目描述:输入一个整数n代表字符串的个数,在接下来的n行每行输出一个字符串,其中输出顺序为长度长的在前短的在后,如果长度相同,字典序大的在前小的在后
3.3字符串中子串的个数
https://pintia.cn/problem-sets/994805260223102976/problems/994805282389999616

4.贪心

贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解。
贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择。也就是说,不从整体最优上加以考虑,做出的只是在某种意义上的局部最优解 。
具体例题讲解一:https://pintia.cn/problem-sets/994805260223102976/problems/994805301562163200
具体例题讲解二:https://pintia.cn/problem-sets/994805260223102976/problems/994805298269634560
区间贪心:
具体例题讲解三:http://codeup.cn/problem.phpcid=100000584&pid=0

4.组合数计算

组合数C(n,m)是指从n个不同的数m中选出n个方案的个数,常见有两种计算方法
4.1根据C(n,m)=n!/m!/(n-m)!

#include <bits/stdc++.h>
using namespace std;
long long sum(int n)//利用递归求n!函数 
{
    
    
	if(n==0||n==1)
	return 1;
	else
	return n*sum(n-1);
}
int main()
{
    
    
  int n,m;
  cin>>n>>m;
  cout<<sum(n)/sum(m)/sum(n-m);//根据公式求答案 
	return 0;
}

4.2根据递推公式C(n,m)=C(n-1,m)+C(n-1,m-1),C(n,n)=C(0,0)=1

#include <bits/stdc++.h>
using namespace std;
long long ans[60][60]; 
long long sum()//利用递归求n!函数 
{
    
    
	for(int i=0;i<60;i++)
	{
    
    
		ans[i][i]=ans[i][0]=1;
	}
	for(int i=2;i<60;i++)
	{
    
    
		for(int j=1;j<=i/2;j++)
		{
    
    
		ans[i][j]=ans[i-1][j]+ans[i-1][j-1];
		ans[i][i-j]=ans[i][j];
	}
	}
}
int main()
{
    
    
      sum();
      cout<<ans[35][28]<<endl<<ans[4][2]<<endl<<ans[5][2]<<endl<<ans[2][1]<<endl<<ans[3][2];
	return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_45432976/article/details/112754552
今日推荐