C/C++ 第十届蓝桥杯大赛省赛真题(大学B组) 题解

#include<bits/stdc++.h>
using namespace std;
int c2=0,c5=0;
int w[101]={0,5650,4542,3554,473,946,4114,3871,9073,90,4329,
2758,7949,6113,5659,5245,7432,3051,4434,6704,3594,
9937,1173,6866,3397,4759,7557,3070,2287,1453,9899,
1486,5722,3135,1170,4014,5510,5120,729,2880,9019,
2049,698,4582,4346,4427,646,9742,7340,1230,7683,
5693,7015,6887,7381,4172,4341,2909,2027,7355,5649,
6701,6645,1671,5978,2704,9926,295,3125,3878,6785,
2066,4247,4800,1578,6652,4616,1113,6205,3264,2915,
3966,5291,2904,1285,2193,1428,2265,8730,9436,7074,
689,5510,8243,6114,337,4096,8199,7313,3685,211};
int main()
{
	for(int i=1;i<=100;i++)
	{int n=w[i]; 我刚开始写错了
		
			while(n%2==0)
			{
				n=n/2;
				c2++;
			}
		
		
			while(n%5==0)
			{
				n=n/5;
				c5++;
			}
		
	}
	cout<<min(c2,c5);
	return 0;
}

这个是就是撑起来后后面有几个0,也就是2*5=10,看这些乘数能拆分为2 和五
但在拆分的时候要想清楚 是他还能整除2 才能继续拆,否则3也能/2.

//1.先给他排序
//2.每两个数之间的差都取最大公约数,然后找到最小的 
//3.最大值-最小值/d +1
#include<bits/stdc++.h>
using namespace std;
int MM=1e5+9;
int gcd(int a,int b)
{
	return a%b==0?b:gcd(b,a%b);//求取最大公约数 
 } 
 int main()
 {
 	int n,k,ans;
 	int w[MM];
 	int Ai[MM];
 	cin>>n;
 	for(int i=1;i<=n;i++)
 	{
 		cin>>w[i];
 	
	 }
	 sort(w+1,w+n);
	 for(int j=2;j<=n;j++)
	 {
	 	Ai[j-1]=w[j]-w[j-1];
	 }
	 for(int i=1;i<=n-1;i++)
	 {
	 	Ai[i]=gcd(Ai[i],Ai[i]);
	 }
	 int dd=Ai[1];
	 for(int i=1;i<=n-1;i++)
{
	dd=gcd(dd,Ai[i]);
}
	 cout<<(w[n]-w[1])/dd+1; 
	 return 0;
  } 
#include<bits/stdc++.h>
using namespace std;
int check(int n)
{
	while(n)
	{
	if(n%10==2||n%10==0||n%10==1||n%10==9)
	return 1;
	
	n=n/10;
}
return 0;
	
 } 
 int main()
 { int n,ans=0;
 	cin>>n;
 	for(int i=1;i<=n;i++)
 	{if(check(i)) 
 	
 		ans+=i;
	 }
	 cout<<ans;
	 return 0;
 }
#include<bits/stdc++.h>
using namespace std;
int judge(int m)
{while(m)
{
	if(m%10==2||m%10==4)
	{
		return 0;
	}
	m=m/10;
} 
return 1;
}

int check(int a,int b,int c)
{
	if(judge(a)&&judge(b)&&judge(c)&&a!=b&&b!=c&&a!=c) return 1;
	return 0;
 } 
 int main()
 {
 	int a,b,c,ans=0;
 	//我老是把i,j,k 写着写着就混淆了,哭了。 其实这个小于谁,不重要,到最后就很明显了,就写等于2019.因为有那麽多条件卡着呢。 
 	for(int i=1;i<=2019;i++)
 	for(int j=i+1;j<=2019;j++)
 	for(int k=j+1;k<=2019;k++)
 	if(i+k+j==2019)
 	ans+=check(i,j,k);
 	
 	cout<<ans;
 	return 0}
#include<bits/stdc++.h>
using namespace std;
void solve(int n)
{
	while(n){
		cout<<(char)(n%26+64); //但是注意要倒过来 因为先出来的是个位  再出来高位 却写到了后面 
		n=n/26;//26进制向左遍历 
	}
 }
 
 int main()
 {
 	solve(2019);
	 return 0; 
  } 
#include<bits/stdc++.h>
using namespace std;
map<string,int> m; 键值对 即m【】
int f(string s)
{
    if(!m[s])//如果子串没有出现过
    {
        set<char>ss;支持唯一元素,防重复的利器
        for(int i=0;i<s.length();i++)
        ss.insert(s[i]);
        m[s]=ss.size();
    }
    return m[s];
    
}
int main()
{
    int i,j,ans=0;
    string s;
    cin>>s;
    for(i=0;i<s.length();i++)
    for(j=1;j<=s.length()-i;j++)
    {
        ans+=f(s.substr(i,j));
    }
    cout<<ans;
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
int miles,year,mon,day=0;
int a[2][13]={
{0,31,28,31,30,31,30,31,31,30,31,30,31},{0,31,29,31,30,31,30,31,31,30,31,30,31}
} ;
int leapyear(int year)
{
	return year%4==0&&year%100!=0 ||year%400==0; 
}
//得到某年某月的天数 
int getNum(int y,int m)
{
	return a[leapyear(y)][m];
}
int check1(int n){//判断回文 
	int sum=0,k=n,x=0;
	while(n)
	{ sum=sum*10;
	sum=sum+n%10; 

	n/=10;
	
		
	}
	return sum==k;
} 
int check2(int n){
	int k=7,w[8];
	while(n)
	{ 
	w[k--]=n%10;
	n=n/10;
	} 
	if(w[0]==w[2]&&w[0]==w[5]&&w[0]==w[7]&&w[1]==w[3]&&w[1]==w[4]&&w[1]==w[6]) return 1;
	return 0;
	
} 
int main()
{int y1,m1,d1,y2,m2,d2,n=0;
bool flag1=1,flag2=1;

cout<<y1<<m1;
cin>>n;
int y=n/10000,m=n/100%100,d=n%100;
while(flag1||flag2)
{
	
	d++;
	if(d>getNum(y,m)) 
	{
		d=1;
		m++;
	}
	if(m>12){
		m=1;
		y++;
	}
	n=y*10000+m*100+d;
	if(check1(n)&&flag1==1)
	{
		y1=y;m1=m;d1=d;
		flag1=0;
	}
	if(check2(n)&&flag2==1)
	{
		y2=y;m2=m;d2=d;
		flag2=0;
	}
}
printf("%04d%02d%02d\n",y1,m1,d1);
printf("%04d%02d%02d\n",y2,m2,d2);
	return 0; 
}

C语言 printf("%02d\n", b);中的%02d是什么意思?

printf格式化输出;要理解%02d得先理解%2d;%2d的意思就是如果数是个位数,比如4;那么输出是 4;即4前面有一个空格;而%02d的意思就是那个空格部分用0补;
如果%5d的输出4是: 4同理如果用%05的输出4就是00004

bool check1(int n) //回文
{
    int sum=0,k=n;
    while(n)
    {
        sum*=10;
        sum+=n%10;
        n/=10;
    }
    return sum==k;
}

上面是正确的,下面我这个写的有一点小问题,应该是完成加上去的操作后,在向左遍历。

int check1(int n){//判断回文 
	int sum=0,k=n,x=0;
	while(n)
	{ sum=sum*10+x; 
	x=n%10;
	n/=10;
	
		
	}
	return sum==k;
} 

看这个哈,这个简直就是一个老套路 看他的循环里面 简称4要素
while的括号内就写你要挨个去每位上的数
然后
你会发现循环体的第一句一般就是操作或者判断,预备跳出循环
2.取该位上的数 %10
3,向左遍历。/10

#include<bits/stdc++.h>
using namespace std;
int miles,year,mon,day=0;
int a[2][13]={
{0,31,28,31,30,31,30,31,31,30,31,30,31},{0,31,29,31,30,31,30,31,31,30,31,30,31}
} ;
int leapyear(int year)
{
	return year%4==0&&year%100!=0 ||year%400==0; 
}
//得到某年某月的天数 
int getNum(int y,int m)
{
	return a[leapyear(y)][m];
}
int main()
{int year=2000,mon=1,day=1,week=6,ans=0,flag=1;
while(flag)
{
	if(year==2020&&mon==10&&day==1&&week==4)
	flag=0;
	
	ans++;
	if(day==1||week==1){
		ans++;
	}
	day++;
	week=week==7?1:week+1;//而且,这个要好好利用一下。
	if(day>getNum(year,mon)) {
		day=1;
		mon++;
	}
	if(mon>12) {
		mon=1;
		year++;
	}
	//我对这一题的感悟是 像这种就是暴力遍历,在遍历的过程中判断情况的这种
//	让我想开了幸运数,都是用while循环,先判断在循环,设置一个flag标志,再开始循环时就判断是不是该跳出了,预备跳出循环。 在每一次循环中得到这次的累加后,就记得前进,是否该进位了。 
	
	
}
cout<<ans;
	return 0; 
}
#include<bits/stdc++.h>
using namespace std;
int a[10009];
int n,j,y=0;
int main()
{cin>>n;
//c存储成绩 //其实不用储存,可以直接输入后就判断,是我想的复杂了。
for(int i=1;i<=n;i++){
	int temp=0;
	cin>>temp;
	a[i]=temp;
}
for(int i=1;i<=n;i++){
	if(a[i]>=60) j++;
	if(a[i]>=85) y++;
} 
//如果是整式运算,当分母大于分子时,结果将永远为0,所以只需要分母乘一个1.0 就可以了
//四舍五入运算就是得到这个数后再加0.5 并强制转换整型。 
double ans1=j/(n*1.0),ans2=y/(n*1.0);
cout<<(int)(ans1*100+0.5)<<"%"<<endl;
	cout<<(int)(ans2*100+0.5)<<"%"<<endl;
	return 0;
}
``
**这个下面是我最原先想写的,用的是vector容器,但是我写a【i】,他说不行,**


```c
#include<bits/stdc++.h>
using namespace std;
vector<int> a[10009];
int n,j,y=0;
int main()
{cin>>n;
//c存储成绩 //其实不用储存,可以直接输入后就判断,是我想的复杂了。
for(int i=1;i<=n;i++){
	int temp=0;
	cin>>temp;
	a[i].push_back(temp);
}
for(int i=1;i<=n;i++){
	if(a[i][0]>=60) j++;
	if(a[i][0]>=85) y++;
} 
//如果是整式运算,当分母大于分子时,结果将永远为0,所以只需要分母乘一个1.0 就可以了
//四舍五入运算就是得到这个数后再加0.5 并强制转换整型。 
double ans1=j/(n*1.0),ans2=y/(n*1.0);
cout<<(int)(ans1*100+0.5)<<"%"<<endl;
	cout<<(int)(ans2*100+0.5)<<"%"<<endl;
	return 0;
}

在这里插入图片描述

因为如果分母也是整形,则表达式的值也是整形。在分母大于分子时,结果永远是零

#include<bits/stdc++.h>
using namespace std;
int a,b,c,d,e,f,g,vis[7],ans=0;
int check()
{
    int cnt=0;
    for(int i=0;i<7;i++)
    cnt+=vis[i];
    if(!cnt) return 0;
    else if(cnt==1||cnt==7)  return 1;
    else //有2~6根管子,判断他们的邻居是不是都没亮
    {
        if(a)
        {
            if(!b&&!f) return 0;
        }
        if(b)
        {
            if(!a&&!g&&!c) return 0;
        }
        if(c)
        {
            if(!b&&!g&&!d) return 0;
        }
        if(d)
        {
            if(!e&&!c)  return 0;
        }
        if(e)
        {
            if(!g&&!d&&!f) return 0;
        }
        if(f)
        {
            if(!a&&!g&&!e)  return 0;
        }
        if(g)
        {
            if(!b&&!c&&!e&&!f) return 0;
        }
        return 1;
    }  
}
int main()
{//七重循环
    for(a=0;a<2;a++)
    for(b=0;b<2;b++)
    for(c=0;c<2;c++)
    for(d=0;d<2;d++)
    for(e=0;e<2;e++)
    for(f=0;f<2;f++)
    for(g=0;g<2;g++){
        vis[0]=a;vis[1]=b;vis[2]=c;vis[3]=d;
        vis[4]=e;vis[5]=f;vis[6]=g;
        ans+=check();
    }
    cout<<ans-3;
    return 0;
}
点评:你看人家这个循环妙的很,就是可以让a-g代表7个灯,然后分别0,1循环
但是如果每个前面加上int 就成了127了,奇怪。而且,确实用STL库容器会比较简单,尤其vector向量容器。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int ans;
ll gcd(ll a,ll b)
{
	return a%b==0?b:gcd(b,a%b);辗转相除法
 } 
 int main()
 {//嵌套循环 来表示两个变化的量
 	for(int i=1;i<=2020;i++)
 	{for(int j=1;j<=2020;j++)
 	{
 		if(gcd(i,j)==1)
 		ans++;
	 }
	 }
	 cout<<ans;
 	return 0;
 }

冒泡排序(BubbleSort)的基本概念是:依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。
在这里插入图片描述

在这里插入图片描述

今天刚刚把老师讲的怎么调试听完,就是打一个断点,程序就会停在那里,按F10往下走,如果比如说我遇到的问题,输出有毛病,emmm,就把断点打在小函数开始的地方。
而且还可以打开监视,把变量拖到下面

在这里插入图片描述

好心酸啊。想要考成电,但是太难了,我太垃圾了,哎呀,算了,先不想那么多,先把手里能做好的先做好,哎呀,真是的,那个临接矩阵就一直不好了,又遇到卡住了,emm,先往后刷题吧,昨天也在搜一些东西,就是
1.成电的人工智能和机器学习
2,关于C++刷题,这个毕竟是底层语言,原来面向对象就是已经有一些函数人家已经给您编好了。好了,继续刷题,开阔思路。

dfs,最近的心得

dfs就是深度寻路算法,嗯,就这吧。
反正就是给你一堆点,某些点之间有这个联系,然后让你输出路径数。
void dfs
{
}
在这里插入图片描述

这个幸运数这是难死我啦,哎呀,我好粗心呀,不过这个跟里面的数没有关系,所以才能模拟 而且不想用a【0】,也可以忽略他。

//我知道了
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
//先写思路:
//用数组模拟,我们可以只看数组里a[1]往后的,是我执拗了,非要把a[0]戴上,是一个循环接力的过程
//先看看有没有被删除的,如果没被删,计数器加1,当加到幸运数时,删除,
//然后把遇到的第一个是0的数,也就是没删,变成1,当得到最后一个幸运数,跳出循环
const int MAX= 1e6+50;
 const int inf =1<<27; 
 int a[MAX]={0}; 
 int flag=0;
 int ans=0;
int main()
{

//{cout<<inf<<endl;
//cout<<pow(2,27);
int m,n;//反正只要m到n之间,直接以n为上界
cin>>m>>n;
int c=0;
int p=2;
a[1]=1;//1代表幸运数 
while(flag==0) 
{int c=0;
	for(int i=1;i<=n;i++)
	{
		if(a[i]!=inf)
		{
			c++;
				if(c==p)
			{
				a[i]=inf;
				 c=0;//记住不要忘了清零 
				 
			}
		}
	}
	
 
	 for(int i=1;i<=n;i++)
	 {
	 	if(i==n) flag=1;//得到最后一个幸运数,准备跳出
		 if(a[i]==0)
		 {
		 	p=i;
		 	a[i]=1;
		 	break;//这个是跳出整个循环 
		  } 
	  } 
  
  } 
  for(int i=m+1;i<n;i++)
  {
  	if(a[i]==1)
  	{
  		ans++;
	}
  }
 
cout<<ans;

	return 0;
}

实在没有思路 可以看一遍答案,搞懂他的思路,就自己动手。这次我成功了,还把前面我新学的知识用进去了,哈哈哈。

#include<iostream>
#include<set>
using namespace std;

struct myComp
{
	bool operator()(const int &a,const int &b)
	{
		return a>b;
	}
};
int main()
{int a,b;
cin>>a>>b;
set<int,myComp> s;
 
	for(int i=0;i<a*b;i++)
	{
		for(int j=0;i*a+j*b<a*b;j++)
		{
			s.insert(i*a+j*b);
		}
	}
set<int,myComp>::iterator it =s.begin();
set<int,myComp>::iterator itTemp=it; 
for(itTemp++;it!=s.end();it++,itTemp++)
{
	while(*itTemp==*it-2)
	{
		cout<<*it-1<<"";
		return 0;
	}
}
	
	return 0;
 } 

一直迷惑的c语言中全局变量和局部变量未初始化时的初始值

c语言中全局变量和局部变量未初始化时的初始值

//没有想到这个竟然也要找规律,不同的位置下标之间的距离 
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
//局部变量必须初始化,只有static和全局变量 不初始化 默认0. 
int main()
{
	int st;
	int ans=0; 
	st=-2;
	
	
	string str1,str2;
	getline(cin,str1);
	getline(cin,str2);
	for(int i=0;i<str1.size();i++)
	{
		if(str1[i]!=str2[i])
		{
			if(st==-2)
			{
				st=i;
			}else
			{
				ans+=(i-st);
				st=-2;
			}
		}
		
	}
		 cout<<ans;
	
	
	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

我今天有了新的发现
1,就是循环体结构有三种 do while while for
for循环我经常用,我发现,大家总是喜欢用int i=0开头,因为数组啥的,就那种存放东西的就开始的下标是0,好了,
for(int i=a;i<=b;i++) 循环b-a次
for(int i=a;i<b;i++) 循环b-a-1次
其实这个也就只是控制循环次数

2.全局和局部都可以先不初始化

#include<iostream>
#include<algorithm>
using namespace std;
int num[10]={1,2,3,4,5,6,7,8,9};
int getNum(int a,int b)
{int Num=0;
	for(int i=a;i<=b;i++)
	{

Num=Num*10+num[i];
	}
 return Num;
}
int main()
{
	int n,a,b,c,ans=0;
	cin>>n;
	do{
		for(int i=0;i<6;i++)
		{
			a=getNum(0,i);
			if(a>n)break;
			if(a<n)
			{
				for(int j=i+1;j<8;j++)
				{
					b=getNum(i+1,j);
					
					c=getNum(j+1,8);
					if(n==(a+b/c)&&b%c==0&&b>=c)
					ans++;
					
				}
			}
		}
		
	  }while(next_permutation(num,num+9));
	  cout<<ans<<endl;
	  return 0;
} 

#include<cstdio>
#include<iostream>
using namespace std;
//1.平方和
int main()
{
	unsigned  long sum=0;
	int th, hu, ten, in;
	for (int i = 1; i <= 2019; i++)
	{
		th = hu = ten = in = 3;//初始化;对,这里不能放0 ,1,2 否则会影响下面
		in = i % 10;

		if (i >= 10)
			th = i/10%10;
		if (i >= 100)
			hu = i / 100 % 10;
		if (i >= 1000)
			th = i / 1000;
		if (th == 2 || th == 0 || th == 1 || th == 9 ||
			hu == 2 || hu == 0 || hu == 1 || hu == 9 ||
			ten == 2 || ten == 0 || ten == 1 || ten == 9 ||
			in == 2 || in == 0 || in == 1 || in == 9 )
		{
			sum += i*i;
		}
	}
	cout << sum << endl;
	return 0;
}
//答案 2658417853

#include <bits/stdc++.h> 万能头文件,包含C/C++中所有的头文件
在这里插入图片描述
我好像懂了,这个不就是那个跟我们那个算进制一样吗,哈哈哈,B组也不是很难。
在这里插入图片描述
我发现了一个致命的错误,这个是你发现他的各位里面有2 4 就返回0 可如果·不说其他返回1,他就都返回0,哭了

这个下面就是x/10 就是往左遍历,%10就是取最后一位,
break和continue,C语言break和continue的用法和区别
我都忘了 continue 是跳出循环的
嵌套循环,就代表j一定大于i,那摸下面k也必须大于i和j,

在这里插入图片描述
在这里插入图片描述

#include<cstdio>
#include<iostream>
using namespace std;

bool check(int num)
{
	int th, hu, ten, in;
	th = hu = ten = in = 0;
	in = num % 10;
	if (num >= 10)
		ten = num / 10 % 10;
	if (num >= 100)
		hu = num / 100 % 10;
	if (num >= 1000)
		th = num / 1000 % 10;
	if (in == 2 || ten == 2 || hu == 2 || th == 2 ||
		in == 4 || ten == 4 || hu == 4 || th == 4)
		return 1;
	else
		return 0;

}
int main()
{
	
	int sy=0;
	for (int i = 1; i <=2019; i++)
	{
		if (check(i)) 
			continue;
		for (int j = i + 1; j <=2019; j++)
		{
			if (check(j))
				continue;
			int k = 2019 - i - j;
			if (k <= i || k <= j || check(k)) continue;
			sy++;
		}

	}
	cout << sy;
	return 0;
}

#include<iostream>
#include<cstdio>
using namespace std;

int Ai[100000];


int main()
{
	int N;
	int deep = 1;
	int sum = 0;
	int max_sum = 1;
	int max_deep=1;
	cin >> N;
	for (int i = 1; i <= N; i++)
	{
		cin >> Ai[i];
		sum += Ai[i];
		if (i == pow(2, deep) - 1)
		{
			if (sum > max_sum)
			{

				max_sum = sum;
				max_deep=deep;
				
				
			}
			sum=0;
			deep++;
		}
	}
	cout << max_deep;
	return 0;
}

在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int gcd(int a, int b)
{
	if (b == 0)
		return a;
	return gcd(b, a%b);
}
int main()
{
	int N;
	int dd;
	const int maxn = 1e5 + 100;//这个务必要大一些,否则他给的数据大就完了。
	int Ai[maxn];
	int ans[maxn];
	cin >> N;
	for (int i = 1; i <= N; i++)
	{
		cin >> Ai[i];


	}
	sort(Ai + 1, Ai + 1 + N);
	for (int j = 2; j <= N; j++)
	{
		ans[j - 1] = Ai[j] - Ai[j-1];
		
	}
	for (int i = 1; i <= N-1; i++)
	{
		dd = gcd(ans[1], ans[i]);
	}
	cout << (Ai[N] - Ai[1]) / dd + 1 << endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值