• 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.密码脱落-方法二
  • 相关阅读:
    Java图片裁剪
    jvm参数
    Druid数据源监控配置
    执行jar包或执行其中的某个类
    十进制和二进制之间的相互转化
    Java位运算
    获取网络资源保存本地
    前端PHP入门-010-内部函数
    前端PHP入门-011-可变函数
    前端PHP入门-009-匿名函数
  • 原文地址:https://www.cnblogs.com/Marginalin/p/12609827.html
Copyright © 2020-2023  润新知