1. 程式人生 > >2016年藍橋杯B組初賽(第七屆)

2016年藍橋杯B組初賽(第七屆)

第一題:
簡單的求和題。

#include<iostream>
#include<cmath>
using namespace std;
int a[110];

int main(){
    int i;
    int sum=0;
    a[1]=1;
    for(i=1;i<100;i++){
        a[i+1]=a[i]+i+1;
    }
    for(i=1;i<=100;i++){
        sum+=a[i];
    }
    cout<<sum<<endl;
    return 0;
}

第二題:
暴力,i,j分別代表起點和終點,遍歷求解,簡單題。
也可以利用等差數列求和公式,求出以i開頭,j結尾等差數列的和。然後遍歷i,j看能不能讓sum恰好等於236

#include<iostream>
#include<cmath>
using namespace std;
int a[110];
int ans=0;
bool flag=false;

int main(){
    int i,j;
    for(i=1;i<=100;i++){
        ans=i;
        for(j=i+1;j<=100;j++){
            ans+=j;
            if
(ans==236){ flag=true; break; } } if(flag) break; } cout<<i<<endl; return 0; }

第三題:
填數字問題,這裡很巧妙的運用了C++中的next_permutation(a,a+n);生成1-9的全排列。(注意標頭檔案#include<algorithm>
開始這道題目寫錯了,那個p,q是double型別,開始寫成了int型別,所以一直是錯的。以後注意型別問題。
還要注意的事情是,next_permutation生成全排列的時候注意要先給陣列賦值。比如a={1,3,4,5};

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int a[11];
int ans=0;
void init(){
    int i;
    for(i=0;i<9;i++){
        a[i]=i+1;
    }
}

void Solve(){
    do{
        double p=1.0*a[1]/a[2];
        double q=1.0*(100*a[3]+10*a[4]+a[5])/(100*a[6]+10*a[7]+a[8]);
        if(a[0]+p+q==10){
            ans++;
        }
    }while(next_permutation(a,a+9));
}

int main(){
    init();
    Solve();
    cout<<ans<<endl;
    return 0;
}

第四題:程式填空-快速排序
剛剛學了快速排序演算法的原理,演算法思路就是:
先選定一個基數,通常選定第一個數就可以;
分別從左到右和從右到左遍歷,從右向左遍歷,使得左邊的數都小於基數,右邊的數都大於基數;再把基數查到對應的位置
這樣一個數組就分成兩端,重複。
這篇部落格講的非常好:
http://blog.csdn.net/kwang0131/article/details/51085734

swap(a,j,p)

第五題:程式填空-遞迴
對於f(int a[],int k,int m,char b[]).a[] 是每個國家的最多指派人數,k表示當前是哪個國家,m表示還需要派送幾個人(可以為負數).b表示已經派送的人的字串。

所以這個題目在遞迴中間的的 第一個迴圈表示從0~a[i]中讓i國選擇指派人數,內迴圈只是向b[]記錄的過程。

f(a,k+1,m-i,b)

第六題:
dfs先填數然後判斷周圍是否可行,八數碼問題。

#include<iostream>
#include<cmath>
using namespace std;
int map[3][4];
int vis[10];
int flag[3][4];
int dir[8][2]={1,0,0,1,0,-1,-1,0,-1,-1,1,1,1,-1,-1,1};
int ans=0;

void init(){
    int i,j;
    for(i=0;i<3;i++){
        for(j=0;j<4;j++){
            flag[i][j]=1;
        }
    }
    flag[0][0]=0;
    flag[2][3]=0;
    memset(vis,0,sizeof(vis));
}

void Solve(){
    int i,j;
    int dx,dy;
    bool book=true;
    for(i=0;i<3;i++){
        for(j=0;j<4;j++){
            if(flag[i][j]==0) continue;
            for(int k=0;k<8;k++){
                dx=i+dir[k][0];
                dy=j+dir[k][1];
                if(dx<0||dx>=3||dy<0||dy>=4||flag[dx][dy]==0) continue;
                if(abs(map[dx][dy]-map[i][j])==1){ book=false;break; }
            }
        }
    }
    if(book){ans++;}
}

void dfs(int index){
    int x=index/4;
    int y=index%4;
    if(x==3){
        Solve();
        return ;
    }
    if(flag[x][y]){
        for(int i=0;i<10;i++){
            if(!vis[i]){
                vis[i]=1;
                map[x][y]=i;
                dfs(index+1);
                vis[i]=0;
            }
        }
    }
    else{
        dfs(index+1);
        }
    }

int main(){
    init();
    dfs(0);
    cout<<ans<<endl;
    return 0;
}

暴力,依舊可以用生成全排列的方法先填數,然後再判斷是否行可行。next_penutation(a,a+n);

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int a[10]={1,2,3,4,5,6,7,8,9,10};
int ans=0;
int main(){
    do{
        int q1=abs(a[0]-a[1])-1;
        int q2=abs(a[0]-a[3])-1;
        int q3=abs(a[0]-a[4])-1;
        int q4=abs(a[0]-a[5])-1;
        int q5=abs(a[1]-a[2])-1;
        int q6=abs(a[1]-a[5])-1;
        int q7=abs(a[1]-a[6])-1;
        int q8=abs(a[2]-a[6])-1;
        int q9=abs(a[3]-a[4])-1;
        int q10=abs(a[3]-a[7])-1;
        int q11=abs(a[3]-a[8])-1;
        int q12=abs(a[4]-a[8])-1;
        int q13=abs(a[4]-a[5])-1;
        int q14=abs(a[4]-a[9])-1;
        int q15=abs(a[5]-a[6])-1;
        int q16=abs(a[5]-a[9])-1;
        int q17=abs(a[1]-a[4])-1;
        int q18=abs(a[2]-a[5])-1;
        int q19=abs(a[4]-a[7])-1;
        int q20=abs(a[5]-a[8])-1;
        int q21=abs(a[6]-a[9])-1;
        int q22=abs(a[7]-a[8])-1;
        int q23=abs(a[8]-a[9])-1;
    if((q1&&q2&&q3&&q4&&q5&&q6&&q7&&q8&&q9&&q10&&q11&&q12&&q13&&q14&&q15&&q16&&q17&&q18&&q19&&q20&&q21&&q22&&q23)!=0){
            ans++;
        }
    }while(next_permutation(a,a+10));
    cout<<ans<<endl;
    return 0;
}

第七題:剪郵票問題
開始寫這道題目的時候一直不知道怎麼判斷5個數是不是連在一起。參考別人的思路終於搞懂了這道題目。
首先先用stl中的next_permutation生成5組數。
然後dfs判斷是否相連。

for(int i=0;i<3;i++){
            for(int j=0;j<4;j++){
                if(!vis[i][j]&&ai[i][j]){
                    num++;
                    dfs(i,j);
                }
            }
        if(num==1) sum++;

這個部分寫的非常有趣。它的意思是如果我一次dfs遍歷過後,如果存在被標記為1的a[i][j](及我們塗色的方格)沒有被訪問過,那麼證明這次我們塗得顏色不相連。應為一次dfs把所有相連的格子都標記了。

#include"iostream"
#include"algorithm"
#include"string.h"
using namespace std;

int ai[3][4];
int bi[12]={0,0,0,0,0,0,0,1,1,1,1,1};
bool vis[3][4];
int num;
int sum=0;
int dir[4][2]={1,0,-1,0,0,-1,0,1};

void dfs(int r,int c){
    if(r<0 ||r>=3||c<0||c>=4) return ;
    if(vis[r][c]||!ai[r][c]) return ;
    vis[r][c]=true;

    for(int i=0;i<4;i++){
        int x=r+dir[i][0];
        int y=c+dir[i][1];
        dfs(x,y);
    }
}

int main(){
    do{
        memset(vis,false,sizeof(vis));
        num=0;
        int flag=0;
        for(int i=0;i<3;i++){
            for(int j=0;j<4;j++){
                ai[i][j]=bi[flag++];
            }
        }

        for(int i=0;i<3;i++){
            for(int j=0;j<4;j++){
                if(!vis[i][j]&&ai[i][j]){
                    num++;
                    dfs(i,j);
                }
            }
        }
        if(num==1) sum++;
    }while(next_permutation(bi,bi+12));
    cout<<sum<<endl;
    return 0;
}

第八題:四平方和問題
暴力,可以開一個三層遍歷,第四層的數可以用總和減去求出來。(如果遍歷四層就會爆掉,==先前寫錯了哎)

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int N;
bool flag=false;

int main(){
    int i,j,k;
    double p;
    cin>>N;
    for(i=0;i*i<N;i++){
        for(j=i;j*j<N;j++){
            for(k=j;k*k<N;k++){
                int q=N-i*i-j*j-k*k;
                //判斷q是不是平方數
                p=sqrt(q);
                if(p==int(p)){ flag=true; break;}
            }
            if(flag) break;
        }
        if(flag) break;
    }
    cout<<i<<" "<<j<<" "<<k<<" "<<p<<endl;
    return 0;
}

第九:交換瓶子
貪心。
將要求瓶子的序號儲存在陣列B中,遍歷陣列A,如果A中當前位置的瓶子序號不對,就交換當前位置的瓶子和要求序號瓶子的位置。記下交換次數。

#include<iostream>
using namespace std;
#define maxn 100010
int a[maxn],b[maxn];
int ans=0;

int main(){
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>a[i];
        b[i]=i+1;
    }
    for(int i=0;i<n;i++){
        if(a[i]!=b[i])
        {
            int temp;
            for(int j=0;j<n;j++)
            {
                if(a[j]==b[i])
                {
                    temp=a[j];
                    a[j]=a[i];
                    a[i]=temp;
                    ans++;
                    break;
                }
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

第十:不會

相關推薦

2016藍橋B初賽

第一題: 簡單的求和題。 #include<iostream> #include<cmath> using namespace std; int a[110]; int main(){ int i; int

2017藍橋B初賽

第一題: 資料處理的題目,簡單題目 第一步,將資料複製到txt文件中 第二步,將資料從txt複製到excel中 第三步,現將資料分列。資料—>分列即可 第四步,替換,ctrl+H.替

2018藍橋B初賽九屆

昨天去南京理工大學參加了藍橋杯,總體感覺比去年難了不少,後面島嶼的題目自己寫的有點可惜。就當一次鍛鍊吧,大三我還會來的。 1.標題:第幾天 2000年的1月1日,是那一年的第1天。 那麼,2000年的5月4日,是那一年的第幾天? 答案:125 2:明碼 漢字的字

2018藍橋Bc/c++ 題詳解

標題:螺旋折線 如圖p1.png所示的螺旋折線經過平面上所有整點恰好一次。 對於整點(X, Y),我們定義它到原點的距離dis(X, Y)是從原點到(X, Y)的螺旋折線段的長度。 例如dis(0, 1)=3, dis(-2, -1)=9 給出整點座標(X, Y),你能計算出di

六角填數|2014藍橋B題解析題-fishers

std 計算 求解 相等 include http 通過 mes esp 六角填數 如圖所示六角形中,填入1~12的數字。 使得每條直線上的數字之和都相同。 圖中,已經替你填好了3個數字,請你計算星號位置所代表的數字是多少? 請通過瀏覽器提交答案,不要填寫多余的內容。 思

2016藍橋BC/C++省賽預選賽試題

2016年藍橋杯B組C/C++ 第一題:煤球數目 有一堆煤球,堆成三角稜錐形。具體: 第一層放1個, 第二層3個(排列成三角形), 第三層6個(排列成三角形), 第四層10個(排列成三角形), .... 如果一共有100層,共有多少個煤球? 請填表示煤球總數目的數字。 注意:你提交的應該是一個整數,

2018藍橋Bc/c++ 九題詳解

標題:全球變暖 你有一張某海域NxN畫素的照片,".“表示海洋、”#"表示陸地,如下所示: ....... .##.... .##.... ....##. ..####. ...###. ....... 其中"上下左右"四個方向上連在一起的一片陸地組成一座島嶼。例如上圖就有2座

2018藍橋Bc/c++ 八題詳解

標題:日誌統計 小明維護著一個程式設計師論壇。現在他收集了一份"點贊"日誌,日誌共有N行。其中每一行的格式是: ts id 表示在ts時刻編號id的帖子收到一個"贊"。 現在小明想統計有哪些帖子曾經是"熱帖"。如果一個帖子曾在任意一個長度為D的時間段內收到不少於K個贊,小明就

2018藍橋Bc/c++ 六題詳解

標題:遞增三元組 給定三個整數陣列 A = [A1, A2, … AN], B = [B1, B2, … BN], C = [C1, C2, … CN], 請你統計有多少個三元組(i, j, k) 滿足: 1 <= i, j, k <= N Ai <

2018藍橋Bc/c++ 三題詳解

標題:乘積尾零 如下的10行資料,每行有10個整數,請你求出它們的乘積的末尾有多少個零? 5650 4542 3554 473 946 4114 3871 9073 90 4329 2758 7949 6113 5659 5245 7432 3051 4434 6704 3594 9

2018藍橋Bc/c++ 十題詳解

標題:乘積最大 給定N個整數A1, A2, … AN。請你從中選出K個數,使其乘積最大。 請你求出最大的乘積,由於乘積可能超出整型範圍,你只需輸出乘積除以1000000009的餘數。 注意,如果X<0, 我們定義X除以1000000009的餘數是負(-X)除以1000000

乘積尾零|2018藍橋B題解析三題-fishers

標題:乘積尾零 如下的10行資料,每行有10個整數,請你求出它們的乘積的末尾有多少個零? 5650 4542 3554 473 946 4114 3871 9073 90 4329 2758 7949 6113 5659 5245 7432 3051 4434 6704 3594 9937 1173 68

遞增三元|2018藍橋B題解析六題-fishers

標題:遞增三元組 給定三個整數陣列 A = [A1, A2, ... AN], B = [B1, B2, ... BN], C = [C1, C2, ... CN], 請你統計有多少個三元組(i, j, k) 滿足: 1 <= i, j, k <= N Ai < Bj <

全球變暖|2018藍橋B題解析九題-fishers

標題:全球變暖 你有一張某海域NxN畫素的照片,"."表示海洋、"#"表示陸地,如下所示: ....... .##.... .##.... ....##. ..####. ...###. ....... 其中"上下左右"四個方向上連在一起的一片陸地組成一座島嶼。例如上圖就有2座島嶼。 由於全球變暖導致

打印圖形|2014藍橋B題解析五題-fishers

藍橋杯 efi int 行程 結果 語句 規模 return 打印 打印圖形 小明在X星球的城堡中發現了如下圖形和文字: rank=3 rank=5 rank = 6 小明開動腦筋,編寫了如下的程序,實現該圖形的打印。 答案:f(a, rank-1, row, col

地宮取寶|2014藍橋B題解析九題-fishers

標簽 需要 names 畫蛇添足 模擬 false 節點 思路 約定 地宮取寶 X 國王有一個地宮寶庫。是 n x m 個格子的矩陣。每個格子放一件寶貝。每個寶貝貼著價值標簽。 地宮的入口在左上角,出口在右下角。 小明被帶到地宮的入口,國王要求他只能向右或向下行走。 走過某

小朋友排隊|2014藍橋B題解析十題-fishers

ostream 拷貝 std 小朋友排隊 names 沒有 都是 歸並 數組 小朋友排隊 n 個小朋友站成一排。現在要把他們按身高從低到高的順序排列,但是每次只能交換位置相鄰的兩個小朋友。 每個小朋友都有一個不高興的程度。開始的時候,所有小朋友的不高興程度都是0。 如果某個

加法變乘法|2015藍橋B題解析六題-fishers

fis fisher continue 其中 示例 main pac 循環 spa 加法變乘法 我們都知道:1+2+3+ ... + 49 = 1225 現在要求你把其中兩個不相鄰的加號變成乘號,使得結果為2015 比如: 1+2+3+...+1011+12+...+272

九數分數|2015藍橋B題解析五題-fishers

turn 答案 dfs 運行 個數字 i++ 分數 stdio.h 回溯法 九數組分數 1,2,3...9 這九個數字組成一個分數,其值恰好為1/3,如何組法? 下面的程序實現了該功能,請填寫劃線部分缺失的代碼。 #include <stdio.h> void

帶分數|2013藍橋B題解析九題-fishers

例如 峰值 包含 整數 全部 標準輸入 出現一次 特征 正整數 帶分數 100 可以表示為帶分數的形式:100 = 3 + 69258 / 714 還可以表示為:100 = 82 + 3546 / 197 註意特征:帶分數中,數字1~9分別出現且只出現一次(不包含0)。 類