蓝桥杯20届(模拟,并查集,dfs,平面几何,dp)

Posted 钟钟终

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥杯20届(模拟,并查集,dfs,平面几何,dp)相关的知识,希望对你有一定的参考价值。

第一题:门牌制作

#include <bits/stdc++.h>

using namespace std;
int cnt;

int main()

    for(int i=1;i<=2020;i++)
    
        int x=i;
        while(x)
        
            int g=x%10;
            if(g==2)
                cnt++;
            x=x/10;
        
    
    cout<<cnt<<endl;
    return 0;

第二题:既约分数

#include <bits/stdc++.h>

using namespace std;
int cnt;
int gcd(int a,int b)

    return b==0?a: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)
            cnt++;
    
    cout<<cnt<<endl;
    return 0;


第三题:蛇形填数

#include <bits/stdc++.h>

using namespace std;


int main()

    int sum=1;
    for(int i=1;i<=20;i++)  //直接根据对角线找规律,绝了
    
        sum+=4*(i-1);
    
    cout<<sum<<endl;
    return 0;


第四题:七段码(并查集+dfs)

#include <bits/stdc++.h>

using namespace std;
int mp[15][15],f[15],ans;
bool vis[15];
void init()

    mp[1][2]=mp[1][6]=mp[2][7]=mp[2][3]=mp[3][7]=mp[3][4]=1;
    mp[4][5]=mp[5][7]=mp[5][6]=mp[6][7]=1;

int r_find(int r)

    if(f[r]!=r)
        f[r]=r_find(f[r]);
    return f[r];

void dfs(int x)

    if(x>7)   //确定这些灯管是否连在一起,用并查集
    
        for(int i=1;i<=7;i++)
            f[i]=i;
        for(int i=1;i<=7;i++)
        
            for(int j=i+1;j<=7;j++)
            
                if(mp[i][j]&&vis[i]&&vis[j])
                
                    int fx=r_find(i),fy=r_find(j);
                    if(fx==fy) continue;
                    f[fx]=fy;
                
            
        
        int k=0;
        for(int i=1;i<=7;i++)   //若使用的灯管可分为几个集合
        
            if(f[i]==i&&vis[i])
                k++;
        
        if(k==1)
            ans++;
        return;
    
    vis[x]=1;  //此灯开
    dfs(x+1);

    vis[x]=0;  //此灯关
    dfs(x+1);

int main()

    init();
    dfs(1);
    cout<<ans<<endl;
    return 0;


第五题:平面分割

/**
 *  平面分割(数学)-----关于直线和圆分隔平面的问题总结*/
#include <bits/stdc++.h>
#define ll long long
using namespace std;
/**
 计算n条直线最多能把平面分成几个部分,n为直线条数  */
ll line(ll n)

    return (n * n + n) / 2 + 1;


/**
  计算n个圆最多能把平面分成几个部分
  圆的个数且n>=1   */
ll circle(ll n)

    return n * (n - 1) + 2;


/**
  计算m个圆和n条直线最多能把平面分成几个部分
    m 圆的个数 ,n 直线条数  */
ll circle_line(ll m, ll n)

    return m * m - m + 2 * m * n + n * (n + 1) / 2 + 1;


int main() 
    ll n, m;
    cout<<"依次输入直线条数和圆的个数:"<<endl;
    scanf("%lld%lld", &n, &m);
    cout<<"直线:";
    printf("%lld\\n",line(n));
    cout<<"圆:";
    printf("%lld\\n", circle(n));
    cout<<"直线+圆:";
    printf("%lld\\n", circle_line(m, n));
    return 0;


第六题:成绩统计

#include <bits/stdc++.h>

using namespace std;
int x1,x2;

int main()

    int n;scanf("%d",&n);
    while(n--)
    
        int x;scanf("%d",&x);
        if(x>=85)
            x1++;
        if(x>=60)
            x2++;
    
    double b=(x2*1.0/7)*100;
    if(b-floor(b)>=0.5)
        cout<<(int)ceil(b)<<"%"<<endl;
    else
        cout<<(int)floor(b)<<"%"<<endl;

    double a=(x1*1.0/7)*100;
    if(a-floor(a)>=0.5)
        cout<<(int)ceil(a)<<"%"<<endl;
    else
        cout<<(int)floor(a)<<"%"<<endl;
    return 0;

第七题:回文日期

#include <bits/stdc++.h>

using namespace std;
int dd[15]=0,31,0,31,30,31,30,31,31,30,31,30,31;
bool check(int y)

    if((y%4==0&&y%100!=0)||(y%400==0))
        return 1;
    return 0;

int n,year,month,day;

int main()

    cin>>n;
    year=n/10000;
    while(1)
    
        year++;
        month=(year%10)*10+(year/10)%10;
        day=((year/100)%10)*10+(year/1000);
        if(month<=12&&day<=31)
        
            if(month==2)
            
                if((check(year)&&day>29)||(!check(year)&&day>28))
                    continue;
                else
                
                    printf("%d%02d%02d\\n",year,month,day);
                    //宽度,若数据小于宽度,在左边补上0
					break;
                
            
            else
            
                if(day<=dd[month])
                
                    printf("%d%02d%02d\\n",year,month,day);
					break;
                
            
        
    
    year=n/1000000;
    while(1)
    
        year++;
        int k,k1=year/10,k2=year%10;
        k=k2*10+k1;
        if(k<=12)
        
            if(k2==2)
            
                cout<<20200202<<endl;break;
            
            else
            
                printf("%02d%02d%02d%02d\\n",year,year,k,k);break;
            
        
    
    return 0;

第八题:子串分值和

#include <bits/stdc++.h>
#define int long long
using namespace std;

signed main()

    string s;
    cin>>s;
    int l=s.length();
    int sum=0;
    int left=0,right=0;
    for(int i=0;i<l;i++)
    
       for(right=i+1;right<l;right++)
       
           if(s[right]==s[i])
            break;
       
       for(left=i-1;left>=0;left--)
       
           if(s[left]==s[i])
            break;
       

       sum+=(right-i)*(i-left);
    
    cout<<sum<<endl;
    return 0;

第九题:平面切分

第十题:字串排序

以上是关于蓝桥杯20届(模拟,并查集,dfs,平面几何,dp)的主要内容,如果未能解决你的问题,请参考以下文章

蓝桥杯之算法模板题 Python版

大力飞砖之DFS与并查集(中-下)

[状压dp] aw3494. 国际象棋(状压dp+第12届蓝桥杯CB组)

蓝桥杯 修改数组 python (并查集)

冲击蓝桥杯-并查集,前缀和,字符串

第十二届蓝桥杯 2021年国赛真题 (Java 大学B组)