蓝桥杯2020年c++B组真题【省赛】

一、门牌制作

 

思路:枚举每一位数,看是否等于2,是的话++;

#include<iostream>
using namespace std;
int ans;
void solve(int k)
{
	while (k > 0)
	{
		int m = k % 10;
		k /= 10;
		if (m == 2)
		{
			ans++;
		}
	}
}
int main()
{
	for (int i = 1; i <= 2020; i++)
	{
		solve(i);
	}
	cout << ans << endl;
	return 0;
}

二、既约分数

 

思路;利用gcd函数,枚举数字后判断是否 符合条件,最后乘二(因为数字可以上下交换)再加一(记得算上1/1)的情况。

#include<iostream>
using namespace std;
int gcd(int a,int b) {
    return b>0 ? gcd(b,a%b):a;
}

int main()
{
	long long int cnt=0;
	for(int i=1;i<=2020;i++){
		for(int j=i+1;j<=2020;j++){
			if(gcd(i,j)==1) cnt++;
		}
	}
	cout<<cnt*2+1;
	return 0;
}

三、蛇形填数

 

思路:找规律,n+1行的数等于第n行数字加n*(n-1). 

#include <bits/stdc++.h>  
using namespace std;  
int main() {  
	int step = 4, n = 1, res = 1;  
	while(res ++) {  
		if(res == 21) break;  
		n += step; step += 4;  
	}  
	cout << n << endl;  
	return 0;  
}

 四、七段码

 

思路;判断二极管是否相连,可以先用二维数组标记两两相连的二极管,再枚举亮灯的情况,利用深搜(dfs)判断枚举出的灯是否相连,再利用并查集将相连的二极管块连在一起,最后判断是否只有一组数据,是的话说明所有二极管都连在了一起。 

#include <iostream>
#include <cstring>
using namespace std;
 
const int MAXN = 25;
int n = 7, ans = 0, path[MAXN], f[MAXN][MAXN], father[MAXN];
int find(int x)
{
    if (x != father[x]) {
        return father[x] = find(father[x]);
    }
    return father[x];
}
 
void dfs(int u, int p, int m)
{
    if (u == m) {
        for (int i = 1; i < MAXN; ++i) {
            father[i] = i;
        }
        for (int i = 0; i < m; ++i) {
            for (int j = i + 1; j < m; ++j) {
                //存在边相连
                if (f[path[i]][path[j]] == 1) {
                    //path[i] 和 path[j] 合并成一个集合
                    father[find(path[i])] = find(father[path[j]]);
                }
            }
        }
        bool flag = false;
        for (int i = 0; i < m - 1; ++i) {
            if (find(path[i]) != find(path[i + 1])) {
                flag = true;
                break;
            }
        }
 
        if (!flag) {
            ++ans;
        }
        return ;
    }
    for (int i = p; i <= n; ++i) {
        path[u] = i;
        dfs(u + 1, i + 1, m);
    }
}
 
int main()
{
    //A B C D E F G
    //1 2 3 4 5 6 7
    memset(f, 0, sizeof(f));
    f[1][2] = f[2][1] = 1;
    f[1][6] = f[6][1] = 1;
    f[2][7] = f[7][2] = 1;
    f[6][7] = f[7][6] = 1;
    f[7][3] = f[3][7] = 1;
    f[7][5] = f[5][7] = 1;
    f[2][3] = f[3][2] = 1;
    f[3][4] = f[4][3] = 1;
    f[4][5] = f[5][4] = 1;
    f[5][6] = f[6][5] = 1;
    for (int i = 1; i <= n; ++i) {
        dfs(0, 1, i);
    }
    cout << ans << endl;
    return 0;
}

五、跑步锻炼

  思路:模拟,但是要注意闰年的判断和每个月的月数。

#include<iostream>
using namespace std;
int ants = 0;
int Month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
int main()
{
	int year = 2000, month = 1, day = 1, weekday = 6;
	while (1)
	{
		ants += (weekday == 1 || day == 1) + 1;
		if (year == 2020 && month == 10 && day == 1)
		{
			break;
		}
		day += 1;
		weekday = (weekday + 1) % 7;
		if (month == 2 && (year % 4 == 0 && year % 100 != 0 || year % 400 == 0))
		{
			if (day > Month[month] + 1)
			{
				day = 1;
				month += 1;
			}
		}
		else if (day > Month[month])
		{
			day = 1;
			month += 1;
		}
		if (month == 13)
		{
			month = 1;
			year += 1;
		}
 
	}
	cout << ants << endl;
	return 0;
}

六、回文日期

 思路:需要用字符串和数字之间的转换,然后判断一个日期是否是回文串,日期是否合法,在前面的基础上再判断是否是ABBABABA即可。

#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <bits/stdc++.h>
using namespace std;
int data;
int mon[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
bool fun(int n){
    string s="";
    while(n){
        int temp=n%10;
        s+=temp-'0';
        n/=10;
    }
    string m=s;
    reverse(s.begin(),s.end());
    return m==s?true:false;
}

bool sfun(int n){
    string s="";
    while(n){
        int temp=n%10;
        s+=temp-'0';
        n/=10;
    }
    string m=s;
    reverse(s.begin(),s.end());
    if(s!=m) return false;
    if(s[2]!=s[0]) return false;
    if(s[3]!=s[1]) return false;
    if(s[4]!=s[1]) return false;
    if(s[5]!=s[0]) return false;
    if(s[6]!=s[1]) return false;
    if(s[7]!=s[0]) return false;
    return true;
}

bool year(int  n){
    int mday=n%100;
    int mmon=(n%10000-mday)/100;
    int myea=(n-n%10000)/10000;
    if((myea%4==0&&myea%100!=0)||(myea%400==0)) mon[2]++;
    if(mmon>12) return false;
    if(mday>mon[mmon]) return false;
    return true;
}

int main(){
    cin>>data;
    int temp;
    for(int i=data+1;;i++){
        if(fun(i)){
            if(year(i)){
                cout<<i<<endl;
                temp=i;
                break;
            }
        }
    }
    for(int i=temp;;i++){
        if(sfun(i)){
            if(year(i)){
                cout<<i<<endl;
                break;
            }
        }
    }
    return 0;
}

七、字串排序

 思路:1、逆序数等于冒泡排序冒泡交换的次数

 

#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
char ans[N], res[N];
int n, len;
bool judge() 
{
	int i = len;
	while(ans[i] == res[i] && i) i--;
	return res[i] < ans[i];
}
void dfs(int now, int maxn, int m, int sum) {
	if(sum == n) 
	{
		if(m < len || (m == len && judge()))
		{
			len = m;
			for(int i = 1; i <= len; i++) 	ans[i] = res[i];
		}
		return;
	}
	if(now >= 26) return ;
	for(int i = 1; i <= maxn; i++) 
	{
		int temp = sum + m * i;
		if(temp > n) return ;
		res[m + i] = char(now + 'a');
		dfs(now + 1, i, m + i, temp);
	}
}
 
int main()
{
    len = 0x3f3f3f3f;
    scanf("%d", &n);
    dfs(0, 8, 0, 0);
    for(int i = len; i >= 1; i--)
		putchar(ans[i]);
	return 0;
}

八、成绩统计

 

思路:先就是对这个数+0.5然后强制成Int就成了,但是也要注意四舍五入的情况。

#include <iostream>
using namespace std;
int main()
{
    double a = 0;
    double b = 0;
    double c;
    cin >> c;
    int n;
    for (int i = 0; i < c; i++)
    {
        cin >> n;
        if (n >= 60)
        {
            a++;
        }
        if (n >= 85)
        {
            b++;
        }
 
    }
    int x =(a * 100.0)/c+0.5;
    int y =(b * 100.0)/c+0.5;
    cout << x << "%" << endl << y << "%";
    return 0;
}

 九、字串分值和

 思路:采用的是贡献值方法

#include <iostream>
using namespace std;
int last[30]; 
long long ans = 0;
int main() {
    string s;
    cin >> s;
    int len = s.length();
    s = '0' + s;
    for (int i = 1; i <= len; i++) {
        ans += (long long)(len - i + 1) * (i - last[s[i]-'a']);
        last[s[i]-'a'] = i;
    }
    cout << ans;
    return 0;
}

十、平面切分

 

思路:下面的直线都优先进行去重,然后进行接下来操作
1.如果新增的直线和一个直线平行,那么就+1
2.如果新增的直线与平面内所有的直线有交点,且这个交点和之前的交点不一样(交点用set去重)那么增加的分割数就是交点数+1。 

 

#include <iostream>
#include <set>
#include <bits/stdc++.h>
using namespace std;

int n;
double A[1005],B[1005];
int main(){
    cin>>n;
    set<pair<double,double> >a;
    while(n--){
        double x;
        double y;
        cin>>x>>y;
        a.insert(pair<double,double>(x,y));
    }
    set<pair<double,double> >:: iterator it=a.begin();
    for(int i=0;i<a.size();i++){
        A[i]=it->first;
        B[i]=it->second;
        it++;
    }
    long long ans = 2;  
    for(int i = 1; i < a.size(); i++)
    {    
        set<pair< double,  double> > pos;  
        for(int j = 0; j <= i-1; j++)
        {
            double a1 = A[i], b1 = B[i];
            double a2 = A[j], b2 = B[j];
            if(a1 == a2) continue;    
            double x= (b2-b1)/(a1-a2);  
            double y= a1*(b2-b1)/(a1-a2) + b1; 
            pos.insert(pair<double,double>(x,y));
        }
        ans += pos.size() + 1;  
    }
    cout<<ans<<endl;
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值