• 第七届蓝桥杯省赛B组整理


    第一题:
    煤球数目

    有一堆煤球,堆成三角棱锥形。具体:
    第一层放1个,
    第二层3个(排列成三角形),
    第三层6个(排列成三角形),
    第四层10个(排列成三角形),
    ....
    如果一共有100层,共有多少个煤球?

    请填表示煤球总数目的数字。
    注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

    思路:

    这个题很好想,找出规律后,循环相加就行。

    第一层放1个,第二层3个,第三层6个,第四层10个。

    得出规律:array[i]=i+arr[i-1] (从i为1开始)

     1 #include<iostream>
     2 using namespace std;
     3 
     4 int arr[101];
     5 
     6 int  main()
     7 {
     8     int sum=0;
     9     for(int i=1;i<=100;i++){
    10         arr[i]=i+arr[i-1];
    11         sum+=arr[i];
    12     }
    13     cout<<sum<<endl;
    14     return 0;
    15 }
    View Code

    第二题:

    生日蜡烛

    某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛。

    现在算起来,他一共吹熄了236根蜡烛。

    请问,他从多少岁开始过生日party的?

    请填写他开始过生日party的年龄数。
    注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

    思路:暴力求解他从几岁开始过生日的,若是他过完这次party刚好吹熄了236根蜡烛,则输出开始的年龄。否则不用判断这次的年龄起始点。

     1 #include<iostream>
     2 using namespace std;
     3 
     4 int main()
     5 {
     6     for(int i=1;i<100;i++){
     7         int sum=0;
     8         for(int j=i;sum<236;j++){
     9             sum+=j;
    10             if(sum==236){
    11                 printf("%d
    ",i);
    12             }
    13         }
    14     }
    15     return 0;
    16 }
    View Code

    第三题:

    凑算式

    这个算式中A~I代表1~9的数字,不同的字母代表不同的数字。

    比如:
    6+8/3+952/714 就是一种解法,
    5+3/1+972/486 是另一种解法。

    这个算式一共有多少种解法?

    注意:你提交应该是个整数,不要填写任何多余的内容或说明性文字。

    思路:这个题可以暴力破解,就是遍历1~9,9个数字的全排列,看看哪一个序列满足情况,就记作一次。全排列可以用两种方法实现1、头文件algorithm中的next_permutation()函数遍历全排列。2、使用dfs遍历全排列。

    next_permutation()

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<string>
     4 using namespace std;
     5 
     6 int arr[10]={1,2,3,4,5,6,7,8,9};
     7 
     8 int main()
     9 {
    10     int count=0;
    11     do{
    12         if(arr[0]+arr[1]*1.0/arr[2]+(arr[3]*100+arr[4]*10+arr[5])*1.0/(arr[6]*100+arr[7]*10+arr[8])==10.0)
    13             count++;
    14 
    15     }while(next_permutation(arr,arr+9));
    16     cout<<count<<endl;
    17     return 0;
    18 }
    View Code

    dfs()方法

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<string>
     4 using namespace std;
     5 int arr[10],Count=0;
     6 bool used[10];
     7 
     8 void dfs(int step)
     9 {
    10     if(step==9){
    11         if(arr[0]+arr[1]*1.0/arr[2]+(arr[3]*100+arr[4]*10+arr[5])*1.0/(arr[6]*100+arr[7]*10+arr[8])==10.0)Count++;
    12 
    13     }
    14     else{
    15         for(int i=1;i<10;i++){
    16             if(!used[i]){
    17                 arr[step]=i;
    18                 used[i]=true;
    19                 dfs(step+1);
    20                 used[i]=false;
    21             }
    22         }
    23     }
    24 }
    25 int main(){
    26     dfs(0);
    27     cout<<Count<<endl;
    28     return 0;
    29 }
    View Code

    第四题:

    快速排序

    排序在各种场合经常被用到。
    快速排序是十分常用的高效率的算法。

    其思想是:先选一个“标尺”,
    用它把整个队列过一遍筛子,
    以保证:其左边的元素都不大于它,其右边的元素都不小于它。

    这样,排序问题就被分割为两个子区间。
    再分别对子区间排序就可以了。

    下面的代码是一种实现,请分析并填写划线部分缺少的代码。

    注意:只填写缺少的内容,不要书写任何题面已有代码或说明性文字。

    思路快速排序无论用什么方法,都是要完成确认基准点左边都是比他小的数据,右面的元素都是比它大的数据(升序的情况)。判断好基准点,头脑中模拟一下就能想明白。

     1 #include <stdio.h>
     2 
     3 void swap(int a[], int i, int j)
     4 {
     5 int t = a[i];
     6 a[i] = a[j];
     7 a[j] = t;
     8 }
     9 
    10 int partition(int a[], int p, int r)
    11 {
    12 int i = p;
    13 int j = r + 1;
    14 int x = a[p];
    15 while(1){
    16 while(i<r && a[++i]<x);
    17 while(a[--j]>x);
    18 if(i>=j) break;
    19 swap(a,i,j);
    20 }
    21 ___swap(a,j,p)___________________;
    22 return j;
    23 }
    24 
    25 void quicksort(int a[], int p, int r)
    26 {
    27 if(p<r){
    28 int q = partition(a,p,r);
    29 quicksort(a,p,q-1);
    30 quicksort(a,q+1,r);
    31 }
    32 }
    33 
    34 int main()
    35 {
    36 int i;
    37 int a[] = {5,13,6,24,2,8,19,27,6,12,1,17};
    38 int N = 12;
    39 
    40 quicksort(a, 0, N-1);
    41 
    42 for(i=0; i<N; i++) printf("%d ", a[i]);
    43 printf("
    ");
    44 
    45 return 0;
    46 }
    View Code

    第五题:

    抽签

    X星球要派出一个5人组成的观察团前往W星。
    其中:
    A国最多可以派出4人。
    B国最多可以派出2人。
    C国最多可以派出2人。
    ....

    那么最终派往W星的观察团会有多少种国别的不同组合呢?

    下面的程序解决了这个问题。
    数组a[] 中既是每个国家可以派出的最多的名额。
    程序执行结果为:
    DEFFF
    CEFFF
    CDFFF
    CDEFF
    CCFFF
    CCEFF
    CCDFF
    CCDEF
    BEFFF
    BDFFF
    BDEFF
    BCFFF
    BCEFF
    BCDFF
    BCDEF
    ....
    (以下省略,总共101行)

     1 #include <stdio.h>
     2 #define N 6
     3 #define M 5
     4 #define BUF 1024
     5 
     6 void f(int a[], int k, int m, char b[])
     7 {
     8     int i,j;
     9     if(k==N){ 
    10         b[M] = 0;
    11         if(m==0) printf("%s
    ",b);
    12         return;
    13     }
    14     
    15     for(i=0; i<=a[k]; i++){
    16         for(j=0; j<i; j++) b[M-m+j] = k+'A';
    17         f(a,k+1,m-i,b);  //填空位置
    18     }
    19 }
    20 int main()
    21 {    
    22     int  a[N] = {4,2,2,1,1,3};
    23     char b[BUF];
    24     f(a,0,M,b);
    25     return 0;
    26 }
    View Code

    仔细阅读代码,填写划线部分缺少的内容。

    注意:不要填写任何已有内容或说明性文字。

     思路:k代表哪一个国家提供的人数,m表示总共还需要的人数,i为本次给它分配的人数。 

       每次递归轮到下一个国家出人。

    第六题:

    方格填数

    如下的10个格子

    填入0~9的数字。要求:连续的两个数字不能相邻。
    (左右、上下、对角都算相邻)

    一共有多少种可能的填数方案?

    请填写表示方案数目的整数。
    注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

    思路:

    可以用dfs遍历查看可以满足条件的情况有多少。

    这里的L代表行,H代表列。

    注意判断好条件:

    当前位置是now,判断now位置是否可以,要判断画斜线的单元格相差的绝对值不为1.。

    注意判断递归的下一个位置。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cmath>
     4 using namespace std;
     5 int arr[5][6],count=0;
     6 bool used[10];
     7 
     8 bool jude(int l,int h,int x)
     9 {
    10     if(abs(arr[l-1][h-1]-x)==1)return true;
    11     if(abs(arr[l-1][h]-x)==1)return true;
    12     if(abs(arr[l][h-1]-x)==1)return true;
    13     if(abs(arr[l-1][h+1]-x)==1)return true; 
    14     
    15     return false;
    16 
    17 }
    18 void dfs(int l,int h)
    19 {
    20     if(l==3&&h==4){
    21         count++;
    22         return;
    23     }
    24     else{
    25         for(int x=0;x<10;x++){
    26                 if(!jude(l,h,x)&& !used[x]){                                    
    27                     arr[l][h]=x;
    28                     used[x]=true;
    29                     if(h<4){
    30                         dfs(l,h+1);
    31                     }
    32                     else if(h==4){
    33                         dfs(l+1,1);
    34 
    35                     }
    36                     used[x]=false;
    37                     }
    38                 }
    39     }
    40 }
    41 
    42 int main()
    43 {
    44     memset(arr,0x3f,sizeof(arr));
    45     //for(int i=0;i<5;i++)cout<<ends<<arr[0][i];
    46     dfs(1,2);
    47     printf("%d
    ",count);
    48     return 0;
    49 }
    View Code

    第七题:

    剪邮票

    如【图1.jpg】, 有12张连在一起的12生肖的邮票。
    现在你要从中剪下5张来,要求必须是连着的。
    (仅仅连接一个角不算相连)
    比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。

    请你计算,一共有多少种不同的剪取方法。

    请填写表示方案数目的整数。
    注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

                     图1                    图2             图3

    这个题刚开始想用dfs做,边判断边选格子,后来觉得这样做不行,错过了很多种情况,主要的原因是探测的方格情况只有一种,一旦回溯过去的路径就再也回不去了,于是参照着网上博友的写法重新又思考了一遍。https://blog.csdn.net/u014552756/article/details/50946197(博友博客),他主要用的方法是先选格子,之后再判断格子是否合法。

     1 #include<iostream>
     2 #include<cstring>
     3 using namespace std;
     4 
     5 int mp[12]={1,2,3,4,6,7,8,9,11,12,13,14};
     6 int aa[5],vis[5],sum=0;
     7 int b[4]={-1,1,-5,5};//左右上下
     8 
     9 void dfs(int n)
    10 {
    11     for(int i=0;i<4;i++){
    12         int v=aa[n]+b[i];
    13         for(int j=1;j<5;j++){
    14             if(!vis[j]&&v==aa[j]){
    15                 vis[j]=true;
    16                 dfs(j);
    17             }
    18         }
    19     }
    20 }
    21 
    22 int main()
    23 {
    24     int count=0;
    25     for(int a=0;a<12;a++)
    26         for(int b=a+1;b<12;b++)
    27             for(int c=b+1;c<12;c++)
    28                 for(int d=c+1;d<12;d++)
    29                     for(int e=d+1;e<12;e++){
    30                         aa[0]=mp[a];
    31                         aa[1]=mp[b];
    32                         aa[2]=mp[c];
    33                         aa[3]=mp[d];
    34                         aa[4]=mp[e];
    35                         memset(vis,0,sizeof(vis));
    36                         vis[0]=1;
    37                         dfs(0);
    38                         int flag=0;
    39                         for(int i=0;i<5;i++){
    40                             if(!vis[i]){
    41                                 flag=1;
    42                             }
    43                         }
    44                         if(!flag)count++;
    45 
    46                     }
    47     cout<<count<<endl;
    48     return 0;
    49 }
    View Code

    第八题:暂时不会

    第九题:

    交换瓶子

    有N个瓶子,编号 1 ~ N,放在架子上。

    比如有5个瓶子:
    2 1 3 5 4

    要求每次拿起2个瓶子,交换它们的位置。
    经过若干次后,使得瓶子的序号为:
    1 2 3 4 5

    对于这么简单的情况,显然,至少需要交换2次就可以复位。

    如果瓶子更多呢?你可以通过编程来解决。

    输入格式为两行:
    第一行: 一个正整数N(N<10000), 表示瓶子的数目
    第二行:N个正整数,用空格分开,表示瓶子目前的排列情况。

    输出数据为一行一个正整数,表示至少交换多少次,才能完成排序。

    例如,输入:
    5
    3 1 2 5 4

    程序应该输出:
    3

    再例如,输入:
    5
    5 4 3 2 1

    程序应该输出:
    2

    资源约定:
    峰值内存消耗 < 256M
    CPU消耗 < 1000ms

    思路:

     1 #include<iostream>
     2 using namespace std;
     3 
     4 const int maxn=10000+1000;
     5 int main()
     6 {
     7     int arr[maxn];
     8     int n;
     9     scanf("%d",&n);
    10     for(int i=0;i<n;i++){
    11         scanf("%d",arr+i);
    12     } 
    13     int ans=0;
    14     for(int i=0;i<n-1;i++){
    15         int Min=arr[i],index=i;
    16         for(int j=i+1;j<n;j++){
    17             if(Min>arr[j])Min=arr[j],index=j;
    18         }
    19         if(index!=i){
    20             swap(arr[index],arr[i]);
    21             ans++;
    22         }
    23     }
    24     cout<<ans<<endl;
    25     return 0;
    26 }
    View Code

    第十题:暂时不会

     

  • 相关阅读:
    函数即变量
    装饰器模型
    团队配合指令
    三元指令
    虚实之门
    for的逻辑
    我写的第4个程序(日志最近行读取函数)
    还在用WebBrowser吗?你out了!
    关于打印机共享的注意事项——又被叫去修电脑了
    MVVM转换器Int2StringConverter基础类
  • 原文地址:https://www.cnblogs.com/habit2021/p/12237815.html
Copyright © 2020-2023  润新知