2020年蓝桥杯省赛 C++ B组

  1. 门牌制作

签到

#include <iostream>
#include <cstring>

using namespace std;

int n,m;

int get(int x)
{
    int cnt = 0;
    while(x)
    {
        if(x%10 == 2) cnt++;
        x/=10;
    }
    return cnt;
}

int main()
{
    n= 2020;
    int ans = 0;
    for(int i = 1; i <= n; i ++)
    {
        ans += get(i);
    }
    cout << ans << endl;
    return 0;
}
  1. 既约分数

知识点:最大公约数gcd

#include <iostream>
#include <cstring>

using namespace std;

int n,m;

int gcd(int a,int b)
{
    if(b == 0) return a;
    return gcd(b,a%b);
}

int main()
{
    n= 2020;
    int ans = 0;
    for(int i = 1; i <= n; i ++)
    {
        for(int j = 1; j <= n; j ++)
        {
            if(gcd(i,j) == 1) ans ++;
        }
    }
    cout << ans << endl;
    return 0;
}
  1. 蛇形填数

知识点:曼哈顿距离

#include <iostream>
#include <cstring>
#include <string>

using namespace std;

int n,m;

int a[100][100];

int main()
{
    int cnt = 1;
    n = 80;
    for(int i = 2; i <= n; i ++)
    {
        if(i%2)
        {
            for(int j = 1; j < i; j ++)
            {
                a[j][i-j] = cnt++;
            }            
        }
        else
        {
            for(int j = i - 1; j >= 1; j --)
            {
                a[j][i-j] = cnt++;
            }
        }

    }
    cout << a[20][20] << endl;
    return 0;
}
  1. 七段码

知识点:连通块,二进制枚举

abcdefg分别对应二进制上每一位,共7位,0表示不存在,1表示存在;

建立各点的连接关系,对每一次枚举的数据查找连通块,如果连通块数量大于2,就不符合题意;

#include <iostream>
#include <cstring>
#include <string>

using namespace std;

int n,m;

int e[100],ne[100],h[100],idx;

void add(int a,int b)
{
    e[idx] = b,ne[idx] = h[a], h[a] = idx ++;
}

bool st[100];

void dfs(int x,int pos)
{
    for(int i = h[pos]; i != -1 ; i = ne[i])
    {
        int j = e[i];
        if(x&(1<<(j-1)) && !st[j])
        {
//            cout << pos << " " << j << " ";
            st[j] = true;
            dfs(x,j);
        }
    }
    return;
}

int check(int x)
{
    int cnt = 0;
//    cout << x << " ";
    memset(st,false,sizeof st);
    for(int i = 0; i < 7; i ++)
    {
        if(x&(1<<i) && !st[i+1])
        {
//            cout << i+1 << " ";
            st[i+1] = true;
            dfs(x,i+1);
            cnt++;
        }
    }    
//    cout << endl;
    return cnt;
}


int main()
{
    int ans = 0;
    memset(h,-1,sizeof h);
    for(int i = 1; i < 6; i++)
    {
        add(i,i+1);
        add(i+1,i);
    }
    add(7,2);
    add(2,7);
    
    add(7,3);
    add(3,7);
    
    add(7,5);
    add(5,7);
    
    add(7,6);
    add(6,7);
    
    add(1,6);
    add(6,1);
    
    for(int i = 1; i <= (1<<7)-1; i ++)
    {
//        cout << i << " " << check(i) << endl;
        if(check(i) < 2)
        {
            ans ++;
        }
    }
    cout << ans << endl;
    return 0;
}
  1. 跑步锻炼

知识点:闰年,模拟

#include <iostream>
#include <cstring>
#include <string>
using namespace std;

int n,m;

int month[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
//             0 1  2  3  4  5  6  7  8  9 10  11 12

int r_month[] = {0,31,29,31,30,31,30,31,31,30,31,30,31};

int check(int x,int y)
{
    if(x%4 == 0 || x%400 == 0)
    {
        return r_month[y];    
    } 
    return month[y];
}

int main()
{
    int sun = 6;
    int cnt = 0;
    for(int i = 2000; i <= 2020; i ++)
    {
        for(int j = 1; j <= 12; j ++)
        {
            for(int k = 1; k <= check(i,j); k++)
            {
                if(sun == 8)
                {
                    sun = 1;
                }
                if(k == 1 || sun == 1)
                {
                    cnt ++;
                }    
                cnt ++;
                sun++;    
                if(i == 2020 && j == 10     && k == 1)
                {
                    cout << cnt << endl;
                    return 0;
                }
            }
        }
    }
    return 0;
}
  1. 回文日期

暴力枚举

#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

int n,m;

int month[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
//             0 1  2  3  4  5  6  7  8  9 10  11 12

int r_month[] = {0,31,29,31,30,31,30,31,31,30,31,30,31};

vector<int> q1,q2;

int check(int x,int y)
{
    if((x%4 == 0 && x%100 != 0) || x%400 == 0)
    {
        return r_month[y];
    } 
    return month[y];
}

bool pd1(int x)
{
    int a[10];
    int cnt  = 1;
    while(x)
    {
        a[cnt] = x % 10;
        cnt++;
        x /= 10;
    }
    for(int i = 1, j = 8; i <= j; i ++,j --)
    {
        if(a[i] != a[j])
        {
            return false;
        }
    }
    return true;
}

bool pd2(int x)
{
    int a[10];
    int kind[10];
    int cnt  = 1;
    for(int i = 0; i <= 9; i ++) kind[i] = 0;
    while(x)
    {
        int t= x % 10;
        kind[t] ++;
        a[cnt] = t;
        cnt++;
        x /= 10;
    }
    int kinds = 0,last = -1;
    for(int i = 0; i <= 9; i++)
    {
        if(kind[i])
        {
            kinds ++;
            last = i;
        } 
    }
    if(kinds == 2)
    {
        string s;
        for(int i = 1; i <= 8; i ++)
        {
            if(a[i] == a[1])
            {
                s += "A";
            }
            else
            {
                s += "B";
            }
        }
        if(s == "ABABBABA")
        {
            return true;
        }
    }
    return false;
}

void solve()
{
    cin >> n;
    int pos1 = upper_bound(q1.begin(),q1.end(),n)-q1.begin();
    int pos2 = upper_bound(q2.begin(),q2.end(),n)-q2.begin();
    cout << q1[pos1] << "\n" << q2[pos2] << endl;
    return;
}

int main()
{    
    for(int i = 1; i <= 9999; i ++)
    {
        for(int j = 1; j <= 12; j ++)
        {
            for(int k = 1; k <= check(i,j); k++)
            {
                int cnt = i * 10000 + j *100 + k;
                if(pd1(cnt))
                {
                    q1.push_back(cnt);
                }                
                if(pd2(cnt))    
                {
                    q2.push_back(cnt);
                }
            }
        }
    }    
    int t;
    cin >> t;
    while(t--)
    {
        solve();
    }
    return 0;
}
  1. 字串排序

蒟蒻还不会

  1. 成绩统计

#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;

int n,m;

int main()
{
    double ji = 0, you = 0;
    cin >> n;
    for(int i = 1; i <= n; i ++)
    {
        int t;
        cin >> t;
        if(t >= 60) ji ++;
        if(t >= 85) you ++;
    }
    double l = ji/(double)n;
    double r = you/(double)n;
    printf("%.0lf%%\n",round(l*100)); 
    printf("%.0lf%%\n",round(r*100)); 
    return 0;
}
  1. 子串分值和

知识点:

#include<iostream>
#include<string>
#define int long long
using namespace std;

int n;

int last[300];

string s;

signed main()
{
    cin >> s;
    n = s.size();
    s = " " + s;
    int ans = 0;
    for(int i = 1; i <= n; i ++)
    {
        ans += (i-last[s[i]] ) * (n - i + 1);
        last[s[i]] = i;
    }
    cout << ans << endl;
    return 0;
}
  1. 平面切分

知识点:点与直线,数论

现有交点n条

与现有的直线相交时,新增的交点m个,答案贡献n+m+1

#include <iostream>
#include <cstring>
#include <string>
#include <set>
#include <utility>
#define int long long
using namespace std;
typedef pair<double,double> PDD;
const int N = 2e5 + 10;

int n,m;

int a[N],b[N];

set<PDD> s;

signed main()
{
    cin >> n;
    for(int i = 1; i <= n; i ++)
    {
        cin >> a[i] >> b[i];
        s.insert({a[i],b[i]});
    }
    int ans = 2,cnt = 0;
    for(auto i:s)
    {
        a[cnt] = i.first;
        b[cnt] = i.second;
        cnt ++;
    }
    for(int i = 1; i < s.size(); i ++)
    {
        double x = a[i];
        double y = b[i];
        set<PDD> t;
        for(int j = 0; j < i; j ++)
        {
            double l = a[j];
            double r = b[j];
            if(l == x) 
                continue;
            double x1 = -(r - y)/(l - x);
            double y1 = x1 * x + y;
            t.insert({x1,y1});
        }
        ans += t.size() + 1;
    }
    cout << ans << endl;
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值