zoukankan      html  css  js  c++  java
  • 2016-第七届蓝桥杯大赛个人赛省赛(软件类)真题 C大学C组

    返回目录

    题目一览:

    1.报纸页数

    2.煤球数目

    3.平方怪圈

    4.打印方块

    5.快速排序

    6.凑算式

    7.寒假作业

    8.冰雹数

    9.卡片换位

    10.密码脱落

    1.报纸页数

    X星球日报和我们地球的城市早报是一样的,
    都是一些单独的纸张叠在一起而已。每张纸印有4版。

    比如,某张报纸包含的4页是:5,6,11,12,
    可以确定它应该是最上边的第2张报纸。

    我们在太空中捡到了一张X星球的报纸,4个页码分别是:
    1125,1126,1727,1728

    请你计算这份报纸一共多少页(也就是最大页码,并不是用了几张纸哦)?

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

    思路:首先要知道报纸的页码是怎么编号的。如下图。

      方案一:已知最小页码的5减去1是4,而最大页码16减去已知最大页面12也是4,这就很巧妙了,设最大页码是x,则有:x-已知最大页码==已知最小页码-1。

      方案二:可以发现每一张的每一面的两个数字相加都是一样的,如下图:16+1 == 15+2 == 14+3 == ... == 9+8,且都比最大页码大1,设最大页码为x,则有:x+1 == 已知最大+已知最小 == 已知较大+已知较小。

    答案:2852

    2.煤球数目

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

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

    思路:枚举

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int main() {
     5     int cnt = 0;
     6     int Ans = 0;
     7     for(int i=1; i<=100; ++i) {
     8         cnt += i;
     9         Ans += cnt;
    10     } 
    11     printf("%d
    ", Ans);
    12     return 0;
    13 }
    2.煤球数目

    答案:171700

    3.平方怪圈

    如果把一个正整数的每一位都平方后再求和,得到一个新的正整数。
    对新产生的正整数再做同样的处理。

    如此一来,你会发现,不管开始取的是什么数字,
    最终如果不是落入1,就是落入同一个循环圈。

    请写出这个循环圈中最大的那个数字。

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

    思路:枚举若干个数字,然后按照要求做个几十遍,期间把最大值保存,然后输出。这若干个数一比对就出来了。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 void work(int x) {
     5     int Max = -1;
     6     printf("%d: ", x);
     7     for(int i=1; i<=20; ++i){
     8         int t = 0;
     9         int xx = x;
    10         while(x) {
    11             int v = x%10;
    12             t = t + v * v;
    13             x /= 10;
    14         }
    15         x = t;
    16         printf("%d ", x);
    17         Max = max(x, Max);
    18     }
    19     printf("Max = %d
    ", Max);
    20     return ;
    21 }
    22 
    23 int main() {
    24     for(int i=1; i<=20; ++i)
    25         work(i);
    26     return 0;
    27 }
    3.平方怪圈

    答案:145

    4.打印方块

    小明想在控制台上输出 m x n 个方格。
    比如 10x4的,输出的样子是:
    +---+---+---+---+---+---+---+---+---+---+
    | | | | | | | | | | |
    +---+---+---+---+---+---+---+---+---+---+
    | | | | | | | | | | |
    +---+---+---+---+---+---+---+---+---+---+
    | | | | | | | | | | |
    +---+---+---+---+---+---+---+---+---+---+
    | | | | | | | | | | |
    +---+---+---+---+---+---+---+---+---+---+

    (如果显示有问题,可以参见【图1.jpg】)

    以下是小明写的程序,请你分析其流程,填写划线部分缺少的代码。

     1 #include <stdio.h>
     2 
     3 //打印m列,n行的方格 
     4 void f(int m, int n)
     5 {
     6     int row;
     7     int col;
     8     
     9     for(row=0; row<n; row++){
    10         for(col=0; col<m; col++) printf("+---");
    11         printf("+
    ");
    12         for(col=0; col<m; col++) printf("|   ");
    13         printf("|
    ");        
    14     }
    15     
    16     printf("+");
    17     _____________________________;   //填空
    18     printf("
    ");
    19 }
    20 
    21 int main()
    22 {
    23     f(10,4);
    24     return 0;
    25 }

    注意:仅仅填写划线部分缺少的内容,不要添加任何已有内容或说明性文字。

    思路:填空的地方注释掉输出一看就知道填写啥了。

    答案:

    for(col=0; col<m; col++) printf("---+");

    5.快速排序

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

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

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

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

     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     ______________________; // 填空
    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 }
    47 
    48 4.快速排序

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

    思路:我们发现在partition函数中,是以a[p]为标尺,在[p, r]中比a[p]大的和比a[p]小的做交换,那么完成之后就是:a[p],小,小,大,大,大。a[p]显然是要与一个数交换的,那么是i,还是j呢(可以输入i,j输出看一下)。因为我们这个partition函数是要求吧所有小于a[p]的数字放到左边,大于的放到右边,而下标i所指的数是大于a[p]的,与其交换就无法满足要求,所以是与j交换。

    答案:

    swap(a, p, j);

    6.凑算式

         B      DEF
    A + --- + ------- = 10
         C      GHI

    (如果显示有问题,可以参见【图1.jpg】)

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

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

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

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

    思路:拉成一维数组全排练+判断,值得注意的是B/C和DEF/GHI都是整除。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
     5 
     6 bool check() {
     7     int x = a[3]*100 + a[4]*10 + a[5];
     8     int y = a[6]*100 + a[7]*10 + a[8];
     9     if((a[1]*y+a[2]*x)%(a[2]*y) != 0) return false;
    10     int t = a[0] + (a[1]*y+a[2]*x)/(a[2]*y);
    11     if(t == 10) return true;
    12     return false;
    13 }
    14 
    15 int main() {
    16     int Ans = 0;
    17     do {
    18         if(check()) Ans++;
    19     }while(next_permutation(a, a+9));
    20     printf("%d
    ", Ans);
    21     return 0;
    22 }
    6.凑算式

    答案:29

    7.寒假作业

    现在小学的数学题目也不是那么好玩的。
    看看这个寒假作业:

    □ + □ = □
    □ - □ = □
    □ × □ = □
    □ ÷ □ = □
    (如果显示不出来,可以参见【图1.jpg】)

    每个方块代表1~13中的某一个数字,但不能重复。
    比如:
    6 + 7 = 13
    9 - 8 = 1
    3 * 4 = 12
    10 / 2 = 5

    以及: 
    7 + 6 = 13
    9 - 8 = 1
    3 * 4 = 12
    10 / 2 = 5

    就算两种解法。(加法,乘法交换律后算不同的方案)

    你一共找到了多少种方案?


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

    思路:其实也是全排列问题,把12个格子看成一维数组,然后填充,最后判断。值得注意的是13!很大,直接跑大约需要一分钟左右,这是填空题所以没什么事。但是我们可以添加几个优化。第22行加的语言可以排除很多无用的排列,大大的提高了效率。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int a[13] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
     5 int Ans;
     6 
     7 bool check() {
     8     if(a[9]%a[10] != 0) return false; // 不能整除 
     9     if(a[0]+a[1] != a[2]) return false; // + - * /
    10     if(a[3]-a[4] != a[5]) return false;
    11     if(a[6]*a[7] != a[8]) return false;
    12     if(a[9]/a[10] != a[11]) return false;
    13     return true;
    14 }
    15 
    16 void dfs(int x) {
    17     if(x == 13) { // 填完了 
    18         if(check()) Ans++;
    19     }
    20     for(int i=x; i<13; ++i) { 
    21         swap(a[x], a[i]);
    22         // 剪枝 不满足加法或减法 的跳过
    23         // 因为加减法所需数字在前面 这样就减少了许多无用的 计算 
    24         if((x==2&&a[0]+a[1]!=a[2]) || (x==5&&a[3]-a[4]!=a[5])) {
    25             swap(a[x], a[i]);
    26             continue;
    27         }
    28         dfs(x+1);
    29         swap(a[x], a[i]);
    30     }
    31 }
    32 
    33 int main() {
    34     dfs(0);
    35     cout << Ans << endl;
    36     return 0;
    37 }
    38 
    39 6.寒假作业
    7.寒假作业

    答案:64

    8.冰雹数

    任意给定一个正整数N,
    如果是偶数,执行: N / 2
    如果是奇数,执行: N * 3 + 1

    生成的新的数字再执行同样的动作,循环往复。

    通过观察发现,这个数字会一会儿上升到很高,
    一会儿又降落下来。
    就这样起起落落的,但最终必会落到“1”
    这有点像小冰雹粒子在冰雹云中翻滚增长的样子。

    比如N=9
    9,28,14,7,22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1
    可以看到,N=9的时候,这个“小冰雹”最高冲到了52这个高度。

    输入格式:
    一个正整数N(N<1000000)
    输出格式:
    一个正整数,表示不大于N的数字,经过冰雹数变换过程中,最高冲到了多少。

    例如,输入:
    10
    程序应该输出:
    52

    再例如,输入:
    100
    程序应该输出:
    9232

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

    请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

    所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

    注意: main函数需要返回0
    注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
    注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

    提交时,注意选择所期望的编译器类型。

    思路:这题很坑,这个N和上面的N不一样,答案是要求1-N这N个数在执行过程中的最大数,不单单只是一个N。记得开long long,不然会溢出。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 typedef long long LL;
     5 
     6 LL work(LL x) {
     7     LL Max = x;
     8     while(x != 1) {
     9         if(x%2) x = 3 * x + 1;
    10         else x /= 2;
    11         Max = max(Max, x);
    12     }
    13     return Max;
    14 }
    15 
    16 int main() {
    17     LL N, Ans=0; cin >> N;
    18     for(LL i=1; i<=N; ++i) {
    19         LL tmp = work(i);
    20         Ans = max(Ans, tmp);
    21     }
    22     printf("%lld
    ", Ans); 
    23     return 0;
    24 }
    9.冰雹数

    9.卡片换位

    你玩过华容道的游戏吗?
    这是个类似的,但更简单的游戏。
    看下面 3 x 2 的格子

    +---+---+---+
    | A | * | * |
    +---+---+---+
    | B | | * |
    +---+---+---+

    在其中放5张牌,其中A代表关羽,B代表张飞,* 代表士兵。
    还有一个格子是空着的。

    你可以把一张牌移动到相邻的空格中去(对角不算相邻)。
    游戏的目标是:关羽和张飞交换位置,其它的牌随便在哪里都可以。

    输入格式:
    输入两行6个字符表示当前的局面

    输出格式:
    一个整数,表示最少多少步,才能把AB换位(其它牌位置随意)

    例如,输入:
    * A
    **B

    程序应该输出:
    17

    再例如,输入:
    A B
    ***

    程序应该输出:
    12


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

    请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

    所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

    注意: main函数需要返回0
    注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
    注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

    提交时,注意选择所期望的编译器类型。

    思路:宽搜题,注释写的很详细。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 char Map[5][5];
     5 int x_p, y_p, x_a, y_a, x_b, y_b;
     6 bool vis[3][3][3][3][3][3]; // 方便检测新得到的状态之前有没有添加过 
     7 int u[4] = {-1, 0, 0, 1}, v[4] = {0, -1, 1, 0};
     8 
     9 struct Node { // 定义一个状态  
    10     int p_x, p_y; // 空格的坐标 
    11     int a_x, a_y; // A点坐标 
    12     int b_x, b_y; // B点坐标 
    13     int step;      // 初始状态到目前的状态所需步数 
    14 };
    15 
    16 void bfs() {
    17     queue<Node> q;
    18     Node Now; // 初始状态 
    19     Now.p_x = x_p, Now.p_y = y_p;
    20     Now.a_x = x_a, Now.a_y = y_a;
    21     Now.b_x = x_b, Now.b_y = y_b;
    22     Now.step = 0; // 步数为0  
    23     q.push(Now); // 压入队列 
    24     while(!q.empty()) { // 队列不为空 
    25         Now = q.front(); q.pop(); // 弹出队列中的第一个状态 
    26         //if(vis[Now.a_x][Now.a_y][Now.b_x][Now.b_y][Now.p_x][Now.p_y]) continue;
    27         vis[Now.a_x][Now.a_y][Now.b_x][Now.b_y][Now.p_x][Now.p_y] = true; // 这是一个新状态 标记遇到过 
    28         if(Now.a_x==x_b && Now.a_y==y_b && Now.b_x==x_a && Now.b_y==y_a) { // A B两点已经交换了 输出 
    29             printf("%d
    ", Now.step);
    30             return ;
    31         }
    32         for(int i=0; i<4; ++i) { // 空格向四个方向走 
    33             int x = Now.p_x + u[i];
    34             int y = Now.p_y + v[i];
    35             if(x<0 || x>1 || y<0 || y>2) continue; // 越界 
    36             Node End = Now; // 空格向四个方向走后的状态 
    37             End.p_x = x, End.p_y = y, End.step++; // 更新空格的位置 
    38             if(x==Now.a_x && y==Now.a_y) // 交换的是A A的新位置就是上一个状态的空格位置 
    39                 End.a_x = Now.p_x, End.a_y = Now.p_y;
    40             if(x==Now.b_x && y==Now.b_y) // 交换的是B B的新位置就是上一个状态的空格位置 
    41                 End.b_x = Now.p_x, End.b_y = Now.p_y;
    42             if(vis[End.a_x][End.a_y][End.b_x][End.b_y][End.p_x][End.p_y]) // 这种情况添加过了 
    43                 continue;
    44             q.push(End); // 把新的情况添加进去 
    45         }
    46     }
    47 }
    48 
    49 int main() {
    50     for(int i=0; i<2; ++i) // 读入
    51         gets(Map[i]);
    52     for(int i=0; i<2; ++i)
    53         for(int j=0; j<3; ++j) { // 查找空格、A、B的位置 
    54             if(Map[i][j] == ' ')
    55                 x_p = i, y_p = j;
    56             if(Map[i][j] == 'A')
    57                 x_a = i, y_a = j;
    58             if(Map[i][j] == 'B')
    59                 x_b = i, y_b = j;
    60         }
    61     memset(vis, false, sizeof(vis));
    62     bfs();
    63     return 0;
    64 }
    9.卡片换位

    10.密码脱落

    X星球的考古学家发现了一批古代留下来的密码。
    这些密码是由A、B、C、D 四种植物的种子串成的序列。
    仔细分析发现,这些密码串当初应该是前后对称的(也就是我们说的镜像串)。
    由于年代久远,其中许多种子脱落了,因而可能会失去镜像的特征。

    你的任务是:
    给定一个现在看到的密码串,计算一下从当初的状态,它要至少脱落多少个种子,才可能会变成现在的样子。

    输入一行,表示现在看到的密码串(长度不大于1000)
    要求输出一个正整数,表示至少脱落了多少个种子。

    例如,输入:
    ABCBA
    则程序应该输出:
    0

    再例如,输入:
    ABDCDCBABC
    则程序应该输出:
    3

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

    请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

    所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

    注意: main函数需要返回0
    注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
    注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

    提交时,注意选择所期望的编译器类型。

    方法一:爆搜,两端若不相等就分别往左、右添加,代码很简短,但时间复杂度数2^n,是会T的。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 string s;
     5 
     6 int dfs(int l, int r, int cnt) {
     7     if(l >= r) return cnt;
     8     if(s[l] != s[r])
     9         return min(dfs(l+1, r, cnt+1), dfs(l, r-1, cnt+1));
    10     else return dfs(l+1, r-1, cnt);
    11 }
    12 
    13 int main() {
    14     cin >> s;
    15     int Ans = dfs(0, s.length()-1, 0);
    16     printf("%d
    ", Ans);
    17     return 0;
    18 }
    9.密码脱落-方法一-超时

    方法二:要求是对称,那我我们把原串翻转一下,在进行对比可以发现两串有3个不同的字母,那么我们添加这三个字母不就好了。所以答案就是长度-LCS(最长公共子序列)。

     1 #include <bits/stdc++.h>
     2 #include <string>
     3 using namespace std;
     4 
     5 string s, r_s;
     6 int a[1010][1010];
     7 
     8 int LCS() {
     9     int len = s.length();
    10     for(int i=1; i<=len; ++i) {
    11         for(int j=1; j<=len; ++j) {
    12             if(s[i-1] == r_s[j-1])
    13                 a[i][j] = a[i-1][j-1] + 1;
    14             else 
    15                 a[i][j] = max(a[i-1][j], a[i][j-1]);
    16         }
    17     }
    18     return a[len][len];
    19 }
    20 
    21 int main() {
    22     cin >> s;
    23     r_s = s;
    24     reverse(r_s.begin(), r_s.end());
    25     int lcs = LCS();
    26     int Ans = s.length() - lcs;
    27     printf("%d
    ", Ans);
    28     return 0;
    29 }
    9.密码脱落-方法二
  • 相关阅读:
    WPF之感触
    C# WinForm 给DataTable中指定位置添加列
    MyEclipse 8.6 download 官方下载地址
    将博客搬至CSDN
    Building Microservices with Spring Cloud
    Building Microservices with Spring Cloud
    Building Microservices with Spring Cloud
    Building Microservices with Spring Cloud
    Building Microservices with Spring Cloud
    Building Microservices with Spring Cloud
  • 原文地址:https://www.cnblogs.com/Marginalin/p/12609827.html
Copyright © 2011-2022 走看看