2020蓝桥c++A组部分题解

在这里,先更新一下部分题的题解,剩余的题目陆续更新完毕哦。
先更新A题

#include<bits/stdc++.h>
using namespace std;
int a[10],cnt;
void fun(int n){
	for(int i=1;n>0;i++){
		a[i]=n%10;
		n/=10;
	}
	for(int i=1;a[i]!=-1;i++){
		if(a[i]==2) cnt++;
	}
}
int main(){
	memset(a,-1,sizeof(a));
	for(int i=1;i<=2020;i++)
	  fun(i);
	cout<<cnt;
	return 0;
}

  统计1-2020中有多少个2。在这里无脑直接做统计,也就是将每个数字中的各个数字位取出,是2就统计,否则不统计。注意一下取出数字每一个的模板。a[i]=n%10,n=n/10;循环条件n>0。
  接着更新B题。

#include<bits/stdc++.h>
using namespace std;
int cnt;
int main(){
	int n;
	for(int i=2;i<=2020;i++){
		for(int j=1;j<=2020;j++)
		{
		   n=__gcd(i,j);
		   if(n>1) continue;
		   else cnt++;	
		}
	}
	cout<<cnt+2020;
	return 0;
}

找既约分数,按照题目要求我们用暴力破解,毕竟还是个填空题。外循环控制分子,内循环控制分母。在这里分子从2开始,因为分子是1的话一定符合题意,在这里没有进一步优化,目的是为了减少思维强度。使用__gcd(x,y)很方便求得最大公约数,注意调用格式就好。
  接着更新C题。

#include<bits/stdc++.h>
using namespace std;
int fun(int i){
	if(i==1) return 1;
	return fun(i-1)+4*(i-1);
}
int main(){
	int i=20;
	cout<<fun(i);
	return 0;
}

C题蛇形填数,这道题目的破解在与找规律呀!可以发现主对角线上满足规律,an=a(n-1)+4(i-1)。有公式,直接写出递归!!!很简单吧。
  接着更新F题

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+5;
int a[maxn];
int main(){
	int n,len=0,sum=0;
	double ave=0;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		len++;
		sum+=a[i];
	}
	ave=sum*1.0/len; 
	sort(a+1,a+len+1);
	cout<<a[len]<<endl<<a[1]<<endl;
	printf("%.2f",ave);
}

非常简单啦,各位还记得自己C语言的上机报告吧!!!我在这用了一个排序,懒了一点。
接着更新D题,七段码。

#include <bits/stdc++.h>
using namespace std;
string str = "0000000";
string vis;
int ans = 0;
//如何检查排列是否合法?
int umap[7][7];
void initmap()
{
    memset(umap, 0, sizeof(umap));
    umap[0][1] = umap[0][5] = 1;
    umap[1][0] = umap[1][2] = umap[1][6] = 1;
    umap[2][1] = umap[2][3] = umap[2][6] = 1;
    umap[3][2] = umap[3][4] = 1;
    umap[4][3] = umap[4][5] = umap[4][6] = 1;
    umap[5][0] = umap[5][4] = umap[5][6] = 1;
    umap[6][1] = umap[6][2] = umap[6][4] = umap[6][5] = 1;
}
void dfs(int curr)
{
    vis[curr] = '0';//标记访问过了
    for (int j = 0; j < 7; ++j)
    {
        if (umap[curr][j] == 1 && vis[j] == '1')
            dfs(j);
    }
}
bool check()
{
    int cnt = 0;
    for (int i = 0; i < 7;++i)
    {
        if(vis[i]=='1')
        {
            dfs(i);
            ++cnt;
        }
    }
    return cnt == 1;
}
int main()
{
    initmap();
    for (int i = 0; i < 7; ++i)
    {
        sort(str.begin(), str.end());
        str[6 - i] = '1';
        do
        {
            vis = str;
            if(check())
                ++ans;

        } while (next_permutation(str.begin(), str.end()));
    }
    cout << ans << endl;
    return 0;
}

  首先,是函数initmap(),作用是定义二维数组,数组每一行和每一列表示每一个数码管,其中a[i][j]=1表示,第i个数码管和第j个数码管是相连的,a[i][j]=0表示的含义是不相连的。

  接着是搜索函数dfs(),含义是访问当前curr的数码管并标记,接着访问与它相邻并且没有被访问过的数码管(0表示被访问,1表示没有被访问),接着进行下一次搜索。
  然后是函数check(),对当前的vis,搜索结果,满足条件在main中使ans++

  最高是main函数,首先初始化数码管的状态,接着利用for循环,利用sort对上一轮循环产生的全排列进行从小到大排序,并更新数码管的访问状态(也就是一次可以挑几个数码管),接着对可行的每一组排列进行检验结果。

补充,next_permutation():简单的说是用来求出全排列。封装在stl库中,大家可以去找别人博客。

接着更新G题,回文日期。

#include <iostream>
using namespace std;

int months[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool check(int y, int m, int d) //判断是否是合法日期
{
    if (d <= 0 || m <= 0 || m >= 13) return false;
    if (m != 2) 
    {
        if (d > months[m]) return false;
    }
    else
    {
        int days = months[2] + (y % 4 == 0 && y % 100 != 0 || y % 400 == 0);
        if (d > days) return false;
    }
    
    return true;
}

int flip(int x)
{
    int res = 0;
    while (x)
    {
        res = res * 10 + x % 10;
        x /= 10;
    }
    return res;
}

bool st1, st2;
int ans1, ans2;

int main()
{
    int n;
    cin >> n;
    
    for (int i = n + 1; i <= 89991231; i++)
    {
        int year = i / 10000, month = i % 10000 / 100, day = i % 100;
        if (check(year, month, day))
        {
            if (i % 10000 == flip(year) && !st1) 
                st1 = true, ans1 = i;
            
            if (i % 10000 == flip(year) && (month / 10 == day / 10) && (month % 10 == day % 10) && !st2) 
                st2 = true, ans2 = i;
        }
        
        if (st1 && st2) break;
    }
    
    printf("%d\n%d\n", ans1, ans2);
    return 0;
}

check函数,就是判断日期是否合法的,比较简单。
flip将数字x进行翻转,比较简单。
定义全局布尔变量,默认值是false,对于main函数,首先读入日期,接着进行遍历,取出年月日,判断是否满足回文数条件,接着在判断是否满足ABABBABA型回文数条件即可。

更新一个题,是B组,跑步锻炼

#include <iostream>
using namespace std;

int DayPerMon[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int weekday = 6;

int RunPerMon(int m){
  int rpm = 2;
  weekday++;
  for(int i = 2; i <= DayPerMon[m]; i++){
    if(weekday%7 != 1) rpm++;
    else rpm += 2;
    weekday++;
//    cout<<(weekday-1)%7<< ' '<<i<< ' '<< rpm<<endl;
  } 
  return rpm;
}

int Run(int y, int m){
  int run_dis = 0;
  if(y%4 == 0 && y%100 != 0 || y%400 == 0)
    DayPerMon[2] = 29;
  else
      DayPerMon[2] = 28;
  run_dis += RunPerMon(m);
//  cout << y<< ' '<< m<< ' '<< run_dis<< endl;
  return run_dis;
}


int main()
{
  int ans = 0;

  for(int i = 2000; i <= 2019; i++)
    for(int j = 1; j <= 12; j++)
      ans += Run(i, j);

  for(int j = 1; j <= 9; j++)
    ans += Run(2020, j);

  ans += 2;

  cout<< ans;

  return 0;
}

第一个函数,计算每个月的跑步距离。直接设置rpm=2(因为月初时直接+2),设置weekday=6,因为2001.1.1是周六,每过一天weekday++,利用%7是否等于1判断是不是周一从。
第二个函数,Run(x,y)判断在x年y个月跑步的距离,要判断一下闰年,当然也别忘了每次判断,因为要改回2月是28天(也就是每次调用的时候,都要用if-else判断,不要只用if)。
main函数直接循环到指定日期就好了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值