天天看點

C++藍橋杯曆屆試題(附代碼)

文章目錄

    • 帶分數【全排列】
    • 錯誤票據

帶分數【全排列】

C++藍橋杯曆屆試題(附代碼)

思想:

題意是用bfs搜尋,我是枚舉出1~9這9個數字的全排列,然後截取成帶分數的3部分,判斷這個帶分數是否等于給定的數即可。

c++有自帶的求全排列的函數next_permutation(beg,end),其中參數beg、end分别表示序列的頭尾疊代器,這個函數按照字典序給出給定序列的下一個排列,如果序列已經是最後一個排列,則next_permutation将序列重排為最小的排列,并傳回false;否則傳回true。

#include<stdio.h>
#include<algorithm>
#include<iostream>
#define ll long long
using namespace std;
const int N=100010;
int number[9];//全排列

int count(int l,int r){  //計算分割開來的數
    int cou=0;
    for(int i=l;i<=r;i++)
        cou=cou*10+number[i];
    return cou;
}

int main(){
    int ans=0;
    int n;
    cin>>n;
    for(int i=0;i<9;i++){
        number[i]=i+1;
    }
    do{
        //for(int i=0;i<9;i++)cout<<number[i];
        //cout<<endl; //輸出全排列的
        for(int i=0;i<7;i++){
             for(int j=1+1;j<8;j++){
                  int a=count(0,i);int b=count(i+1,j);int c=count(j+1,8);
                  if((a+b/c)!=n||b%c!=0)continue;
                  ans++;
             }
        }
    }while(next_permutation(number,number+9));
    cout<<ans<<endl;
    return 0;
}
           

錯誤票據

傳送門

題目:

C++藍橋杯曆屆試題(附代碼)

由于輸入有行數要求,故可以用字元串來讀取每行,然後以空格為分界點進行讀取各個數字。

關鍵的點就是atoi()函數的使用 atoi—ASCII to integer,将字元串轉換成整形,從數字或正負号開始轉換,一直到非數字為止

更多關于atoi()和itoa()等類似函數用法詳解見部落格:整型與字元串轉換函數atoi和itoa函數詳解

在資料量比較小的情況下可以借鑒下桶排序的思想,開辟一個整型數組(num),用來标記讀取到的每一個數,記錄其出現的次數,初始化全為0,故m既是數組值為0所對應的下标,n即是數組值為2所對應的下标。

代碼參考于:https://blog.csdn.net/eagle_or_snail/article/details/62439327

AC代碼

#include <stdio.h>
#include <string.h>
#include <string>
#include <utility>
#include <iostream>
#include <cstdlib>
const int MAXN = 100010;
using namespace std;

int num[MAXN];
char s[10];//存空格間的數字
int main(){
    int n,l,r,a;
    int max_=0;
    scanf("%d\n",&n);
    memset(num,0,sizeof(num));
    for (int e = 0; e < n; ++e)
    {
        char tmp[400];//存每一行
        gets(tmp);
        int id=0;
        for(int i=0;i<strlen(tmp);i++){
            if(tmp[i]==' '){
                a=atoi(s);//空格間的數字,第一次s就是第一個“ ”前的數字
                id=0;
                memset(s,0,sizeof(s));//重新清空數組
                num[a]++;
                //cout<<a<<endl;
                max_=max(a,max_);//記錄最大值
            }
            s[id++]=tmp[i];//“ ”前的數字加入s
        }
        a=atoi(s);//最後一個數字
        id=0;
        memset(s,0,sizeof(s));
        num[a]++;
        //cout<<a<<endl;
        max_=max(a,max_);
    }
    int k;
    for(k=0;k<=MAXN;k++){
        if(num[k]!=0)break;//把前面沒有的數字先跑過去
    }
    //cout<<k<<endl;;
    for(k;k<=max_;k++){
        if(num[k]==0)l=k;
        if(num[k]==2)r=k;
    }
    cout<<l<<" "<<r<<endl;        
    return 0;
}
           

繼續閱讀