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

    返回目录

    题目一览:

    1.哪天返回

    2.猴子分香蕉

    3.明码

    4.第几个幸运数

    5.书号验证

    6.稍小分数

    7.次数差

    8.等腰三角形

    9.小朋友崇拜圈

    10.耐摔指数

    1.哪天返回

    小明被不明势力劫持。后莫名其妙被扔到x星站再无问津。小明得知每天都有飞船飞往地球,但需要108元的船票,而他却身无分文。
    他决定在x星战打工。好心的老板答应包食宿,第1天给他1元钱。
    并且,以后的每一天都比前一天多2元钱,直到他有足够的钱买票。
    请计算一下,小明在第几天就能凑够108元,返回地球。

    要求提交的是一个整数,表示第几天。请不要提交任何多余的内容。

    思路:模拟就好。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int main() {
     5     int days = 0, money = 0, pay = 1;
     6     do {
     7         days ++;
     8         money += pay;
     9         pay += 2;
    10     } while(money < 108);
    11     cout << days << endl;
    12     return 0;
    13 }
    1.哪天返回

     答案:11

    2.猴子分香蕉解

    5只猴子是好朋友,在海边的椰子树上睡着了。这期间,有商船把一大堆香蕉忘记在沙滩上离去。
    第1只猴子醒来,把香蕉均分成5堆,还剩下1个,就吃掉并把自己的一份藏起来继续睡觉。
    第2只猴子醒来,重新把香蕉均分成5堆,还剩下2个,就吃掉并把自己的一份藏起来继续睡觉。
    第3只猴子醒来,重新把香蕉均分成5堆,还剩下3个,就吃掉并把自己的一份藏起来继续睡觉。
    第4只猴子醒来,重新把香蕉均分成5堆,还剩下4个,就吃掉并把自己的一份藏起来继续睡觉。
    第5只猴子醒来,重新把香蕉均分成5堆,哈哈,正好不剩!

    请计算一开始最少有多少个香蕉。

    需要提交的是一个整数,不要填写任何多余的内容。

    思路:暴力枚举桃子的数量,然后判断符不符合要求。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int main() {
     5     for(int Ans=1000; Ans<=10000; ++Ans) {
     6         if(Ans%5 == 1) {
     7             int a = (Ans-1) / 5 * 4;
     8             if(a%5 == 2) {
     9                 int b = (a-2) / 5 * 4;
    10                 if(b%5 == 3) {
    11                     int c = (b-3) / 5 * 4;
    12                     if(c%5 == 4) {
    13                         int d = (c-4) / 5 * 4;
    14                         if(d%5 == 0) {
    15                             printf("%d
    ", Ans);
    16                             //printf("%d
    ", d);
    17                             return 0;
    18                         }
    19                     }
    20                 }
    21             } 
    22         }
    23     }
    24     return 0;
    25 }
    2.猴子分香蕉

    答案:3141 

    3.明码

    汉字的字形存在于字库中,即便在今天,16点阵的字库也仍然使用广泛。
    16点阵的字库把每个汉字看成是16x16个像素信息。并把这些信息记录在字节中。

    一个字节可以存储8位信息,用32个字节就可以存一个汉字的字形了。
    把每个字节转为2进制表示,1表示墨迹,0表示底色。每行2个字节,
    一共16行,布局是:

    第1字节,第2字节
    第3字节,第4字节
    ....
    第31字节, 第32字节

    这道题目是给你一段多个汉字组成的信息,每个汉字用32个字节表示,这里给出了字节作为有符号整数的值。

    题目的要求隐藏在这些信息中。你的任务是复原这些汉字的字形,从中看出题目的要求,并根据要求填写答案。

    这段信息是(一共10个汉字):

    4 0 4 0 4 0 4 32 -1 -16 4 32 4 32 4 32 4 32 4 32 8 32 8 32 16 34 16 34 32 30 -64 0 
    16 64 16 64 34 68 127 126 66 -124 67 4 66 4 66 -124 126 100 66 36 66 4 66 4 66 4 126 4 66 40 0 16 
    4 0 4 0 4 0 4 32 -1 -16 4 32 4 32 4 32 4 32 4 32 8 32 8 32 16 34 16 34 32 30 -64 0 
    0 -128 64 -128 48 -128 17 8 1 -4 2 8 8 80 16 64 32 64 -32 64 32 -96 32 -96 33 16 34 8 36 14 40 4 
    4 0 3 0 1 0 0 4 -1 -2 4 0 4 16 7 -8 4 16 4 16 4 16 8 16 8 16 16 16 32 -96 64 64 
    16 64 20 72 62 -4 73 32 5 16 1 0 63 -8 1 0 -1 -2 0 64 0 80 63 -8 8 64 4 64 1 64 0 -128 
    0 16 63 -8 1 0 1 0 1 0 1 4 -1 -2 1 0 1 0 1 0 1 0 1 0 1 0 1 0 5 0 2 0 
    2 0 2 0 7 -16 8 32 24 64 37 -128 2 -128 12 -128 113 -4 2 8 12 16 18 32 33 -64 1 0 14 0 112 0 
    1 0 1 0 1 0 9 32 9 16 17 12 17 4 33 16 65 16 1 32 1 64 0 -128 1 0 2 0 12 0 112 0 
    0 0 0 0 7 -16 24 24 48 12 56 12 0 56 0 -32 0 -64 0 -128 0 0 0 0 1 -128 3 -64 1 -128 0 0

    注意:需要提交的是一个整数,不要填写任何多余内容。

    思路:就是一题模拟题,把数字转化成二进制输出就好。值得注意的是负数怎么求它的补码。1.先求出负数的绝对值的二进制,然后从有到左遍历,遇到第一个1时,将其左侧全部取反,右侧和它本身不变。例如01100100 -> 10011100

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 void work(int x) {
     5     int arr[15], flag = 0;
     6     if(x < 0) flag = 1, x=-x;
     7     for(int i=0; i<=7; ++i) {
     8         arr[i] = x%2;
     9         x /= 2;
    10     }
    11     if(flag) // 负数 
    12         for(int i=0; i<=7; ++i)
    13             if(arr[i]==1 && i<7) {
    14                 for(int j=i+1; j<=7; ++j)
    15                     arr[j] = 1 - arr[j];
    16                 break;
    17             }
    18     for(int i=7; i>=0; --i) {
    19         if(arr[i] == 0) printf(" ");
    20         else printf("*");
    21     }
    22 }
    23 
    24 int main() {
    25     int i = 10;
    26     while(i--) {
    27         for(int j=1; j<=16; ++j) {
    28             int a;
    29             scanf("%d", &a);
    30             work(a);
    31             scanf("%d", &a);
    32             work(a);
    33             printf("
    ");
    34         }
    35         printf("
    ");
    36         printf("
    ");
    37     }
    38     return 0;
    39 }
    3.明码

     答案:‭387420489‬

    4.第几个幸运数

    到x星球旅行的游客都被发给一个整数,作为游客编号。
    x星的国王有个怪癖,他只喜欢数字3,5和7。
    国王规定,游客的编号如果只含有因子:3,5,7,就可以获得一份奖品。

    我们来看前10个幸运数字是:
    3 5 7 9 15 21 25 27 35 45
    因而第11个幸运数字是:49

    小明领到了一个幸运数字 59084709587505,他去领奖的时候,人家要求他准确地说出这是第几个幸运数字,否则领不到奖品。

    请你帮小明计算一下,59084709587505是第几个幸运数字。

    需要提交的是一个整数,请不要填写任何多余内容。

    思路:枚举3、5、7的个数,当乘积小于59084709587505时说明这个数是在其前面,所以计数器加1.

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const long long N = 59084709587505;
     5 
     6 bool check(int x, int y, int z) {
     7     long long sum = 1;
     8     while(x--) {
     9         sum *= 3;
    10         if(sum >= N) return false;
    11     }
    12     while(y--) {
    13         sum *= 5;
    14         if(sum >= N) return false;
    15     }
    16     while(z--) {
    17         sum *= 7;
    18         if(sum >= N) return false;
    19     }
    20     //printf("***%lld***
    ", sum);
    21     return true;
    22 }
    23 
    24 int main() {
    25     int n = 0;
    26     for(int i=0; i<=31; ++i) {
    27         for(int j=0; j<=20; ++j) {
    28             for(int k=0; k<=17; ++k) {
    29                 if(check(i, j, k)) n++;
    30             }
    31         }
    32     }
    33     printf("%d
    ", n);
    34     return 0;
    35 }
    4.第几个幸运数

    答案:1905

    5.书号验证

    2004年起,国际ISBN中心出版了《13位国际标准书号指南》。
    原有10位书号前加978作为商品分类标识;校验规则也改变。
    校验位的加权算法与10位ISBN的算法不同,具体算法是:
    用1分别乘ISBN的前12位中的奇数位(从左边开始数起),用3乘以偶数位,乘积之和以10为模,10与模值的差值再对10取模(即取个位的数字)即可得到校验位的值,其值范围应该为0~9。

    下面的程序实现了该算法,请仔细阅读源码,填写缺失的部分。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 // 验证成功返回1,否则返回0 
     5 int f(const char* s) {
     6     int k=1;
     7     int sum = 0;
     8     int i; 
     9     for(i=0; s[i]!=''; i++) {
    10         char c = s[i];
    11         if(c=='-' || c==' ') continue;
    12         sum += _________________________________________ ; //填空
    13         k++;
    14         if(k>12) break; 
    15     }
    16     while(s[i]!='') i++;
    17     return (s[i-1]-'0') == (10-sum % 10)%10;
    18 }
    19 
    20 int main() {
    21     printf("%d
    ",f("978-7-301-04815-3"));
    22     printf("%d
    ",f("978-7-115-38821-6"));    
    23     return 0;
    24 }

    注意:只提交空缺的代码,不要抄写已经存在的代码。

    思路:题目读完就很明显了。

    答案

    k%2? (c-'0'):3*(c-'0')

    6.稍小分数

    回到小学----
    真分数:分子小于分母的分数
    既约分数:分子分母互质,也就是说最大公约数是1

    x星球数学城的入口验证方式是:
    屏幕上显示一个真分数,需要你快速地找到一个比它小的既约分数,要求这个分数越大越好。
    同时限定你的这个分数的分母不能超过100。

    如下代码很暴力地解决了这个问题,请仔细分析,并填写划线部分缺失的代码。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int gcd(int a, int b) {
     4     if(b==0) return a;
     5     return gcd(b,a%b);    
     6 }
     7 
     8 int main() {
     9     // 这是屏幕上显示的那个分数 a/b
    10     int a = 7;
    11     int b = 13;
    12     
    13     int m,n;
    14     int max_a = 0;
    15     int max_b = 1; 
    16     
    17     for(n=100; n>1; n--) {
    18         for(m=n-1; m>=1; m--) {
    19             if(m*b<a*n && gcd(m,n)==1) {
    20                 if( __________________________________ ){ //填空
    21                     max_a = m;
    22                     max_b = n;
    23                     break;
    24                 }
    25             }
    26         }
    27     }
    28     
    29     printf("%d/%d
    ", max_a, max_b);    
    30     return 0;
    31 }
    6.稍小分数

    注意:仅仅填写缺少的代码,不要抄写任何已经存在的代码。

    思路:从第19行的m*b<a*n可知这里是找到一个a/b > m/n的两个数,同时题目要求这个分数越大越好,那么就是需要满足:m/n > max_a/max_b才会进行交换,那么十字相乘展开便得到了答案。

    答案

    max_a*n < max_b*m

    7.次数差

    x星球有26只球队,分别用a~z的26个字母代表。他们总是不停地比赛。
    在某一赛段,哪个球队获胜了,就记录下代表它的字母,这样就形成一个长长的串。
    国王总是询问:获胜次数最多的和获胜次数最少的有多大差距?(当然,他不关心那些一次也没获胜的,认为他们在怠工罢了)

    输入,一个串,表示球队获胜情况(保证串的长度<1000)

    要求输出一个数字,表示出现次数最多的字母比出现次数最少的字母多了多少次。

    比如:
    输入:
    abaabcaa

    则程序应该输出:
    4

    解释:a出现5次,最多;c出现1次,最少。5-1=4

    再比如:
    输入:
    bbccccddaaaacccc

    程序应该输出:
    6

    资源约定:
    峰值内存消耗(含虚拟机) < 256M
    CPU消耗 < 1000ms


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

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

    提交程序时,注意选择所期望的语言类型和编译器类型。

    思路:统计一下每个字母出现的次数,然后for一下找到最大值与最小值,输出差即可。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 char s[1001];
     5 int cnt[27], len;
     6 int Max=-1001, Min=1001;
     7 
     8 int main() {
     9     cin >> s;
    10     len = strlen(s);
    11     for(int i=0; i<len; ++i) 
    12         cnt[s[i]-'a']++;
    13     for(int i=0; i<26; ++i) {
    14         if(!cnt[i]) continue;
    15         Max = Max>cnt[i]? Max:cnt[i];
    16         Min = Min<cnt[i]? Min:cnt[i];
    17     }
    18     cout << Max-Min << endl;
    19     return 0;
    20 }
    7.次数差

    8.等腰三角形

    本题目要求你在控制台输出一个由数字组成的等腰三角形。
    具体的步骤是:
    1. 先用1,2,3,...的自然数拼一个足够长的串
    2. 用这个串填充三角形的三条边。从上方顶点开始,逆时针填充。
    比如,当三角形高度是8时:

    1
    2 1
    3 8
    4 1
    5 7
    6 1
    7 6
    891011121314151

    显示不正确时,参看:p1.png

    输入,一个正整数n(3<n<300),表示三角形的高度
    输出,用数字填充的等腰三角形。

    为了便于测评,我们要求空格一律用"."代替。

    例如:
    输入:
    5

    程序应该输出:
    ....1
    ...2.1
    ..3...2
    .4.....1
    567891011

    再例如:
    输入:
    10

    程序应该输出:
    .........1
    ........2.2
    .......3...2
    ......4.....2
    .....5.......1
    ....6.........2
    ...7...........0
    ..8.............2
    .9...............9
    1011121314151617181

    再例如:
    输入:
    15

    程序应该输出:

    ..............1
    .............2.3
    ............3...2
    ...........4.....3
    ..........5.......1
    .........6.........3
    ........7...........0
    .......8.............3
    ......9...............9
    .....1.................2
    ....0...................8
    ...1.....................2
    ..1.......................7
    .1.........................2
    21314151617181920212223242526


    资源约定:
    峰值内存消耗(含虚拟机) < 256M
    CPU消耗 < 1000ms


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

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

    提交程序时,注意选择所期望的语言类型和编译器类型。

     思路:一道模拟题。步骤如下:

    1. 我们先把1-500(其实350足够)这些数字分解成一位一位的放在s数组里面,然后将存放三角形的数组置为-1,方便与数字分开。

    2. 观察三角形可知一共需要4*(n-1)个数字,开始模拟。

    3. 知道拐点的特点,好改变方向。

    4. 填充完成后打印,值为非负数输出,值为-1输出"."

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int s[10101], len;
     5 int Map[901][901], n;
     6 
     7 void init() {
     8     for(int i=1; i<=500; ++i) {
     9         int x = i;
    10         if(x < 10) s[++len] = x;
    11         else if(x>=10 && x<100) {
    12             s[++len] = x/10;
    13             s[++len] = x%10;
    14         }
    15         else if(x>=100) {
    16             s[++len] = x/100;
    17             s[++len] = x/10%10;
    18             s[++len] = x%10;
    19         }
    20     }
    21     for(int i=1; i<=n; ++i)
    22         for(int j=1; j<=2*n-1; ++j)
    23             Map[i][j] = -1;
    24 }
    25 
    26 void print() {// 打印 
    27     for(int i=1; i<=n; ++i) { 
    28         for(int j=1; j<=2*n-1; ++j) {
    29             if(Map[i][j] == -1) printf(".");
    30             else printf("%d", Map[i][j]);
    31             if(j >= n+i-1) break;
    32         }
    33         printf("
    ");
    34     } 
    35 }
    36 
    37 int main() {
    38     scanf("%d", &n);
    39     init(); // 第一步 用数字填充数组 Map数组置为-1 
    40     int x = 1, y = n;
    41     int flag = 1;
    42     for(int i=1; i<=4*(n-1); ++i) { // 填充这么多数字 
    43         Map[x][y] = s[i];
    44         if(flag == 1) x++, y--; // 左下填充 
    45         if(flag == 2) y++;        // 向右填充 
    46         if(flag == 3) x--, y--; // 左上填充 
    47         if(x==n && y==1) flag = 2; // 左下角 
    48         if(x==n && y==2*n-1) flag = 3; // 右下角 
    49     }
    50     print(); 
    51     return 0;
    52 }
    8.等腰三角形

    9.小朋友崇拜圈

    班里N个小朋友,每个人都有自己最崇拜的一个小朋友(也可以是自己)。
    在一个游戏中,需要小朋友坐一个圈,
    每个小朋友都有自己最崇拜的小朋友在他的右手边。
    求满足条件的圈最大多少人?

    小朋友编号为1,2,3,...N
    输入第一行,一个整数N(3<N<100000)
    接下来一行N个整数,由空格分开。

    要求输出一个整数,表示满足条件的最大圈的人数。

    例如:
    输入:
    9
    3 4 2 5 3 8 4 6 9

    则程序应该输出:
    4

    解释:

    如图p1.png所示,崇拜关系用箭头表示,红色表示不在圈中。
    显然,最大圈是[2 4 5 3] 构成的圈


    再例如:
    输入:
    30
    22 28 16 6 27 21 30 1 29 10 9 14 24 11 7 2 8 5 26 4 12 3 25 18 20 19 23 17 13 15

    程序应该输出:
    16


    资源约定:
    峰值内存消耗(含虚拟机) < 256M
    CPU消耗 < 1000ms


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

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

    提交程序时,注意选择所期望的语言类型和编译器类型。

    思路:题目的大概意思是在一个有向图中寻找一个最大的环,那么我们就可以从每一个小朋友开始dfs,找到环之后更新答案。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int MAXN = 100000 + 10;
     5 
     6 bool vis[MAXN];
     7 int n, kids[MAXN], Ans=-MAXN;
     8 
     9 void dfs(int x, int xx, int len) {
    10     if(vis[x] && x==xx) { //经过一圈后回来了 
    11         Ans = Ans<len? len:Ans;
    12         return ;
    13     }
    14     if(vis[x]) return ; 
    15     vis[x] = true;
    16     dfs(kids[x], xx, len+1);
    17     return ;
    18 }
    19 
    20 int main() {
    21     cin >> n;
    22     for(int i=1; i<=n; ++i)    scanf("%d", &kids[i]);
    23     for(int i=1; i<=n; ++i) {
    24         memset(vis, false, sizeof(vis));
    25         dfs(i, i, 0);
    26     }
    27     cout << Ans << endl;
    28     return 0;
    29 }
    9.小朋友崇拜圈

    10.耐摔指数

    x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机。
    各大厂商也就纷纷推出各种耐摔型手机。x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后才允许上市流通。

    x星球有很多高耸入云的高塔,刚好可以用来做耐摔测试。塔的每一层高度都是一样的,与地球上稍有不同的是,他们的第一层不是地面,而是相当于我们的2楼。

    如果手机从第7层扔下去没摔坏,但第8层摔坏了,则手机耐摔指数=7。
    特别地,如果手机从第1层扔下去就坏了,则耐摔指数=0。
    如果到了塔的最高层第n层扔没摔坏,则耐摔指数=n

    为了减少测试次数,从每个厂家抽样3部手机参加测试。

    如果已知了测试塔的高度,并且采用最佳策略,在最坏的运气下最多需要测试多少次才能确定手机的耐摔指数呢?

    输入数据,一个整数n(3<n<10000),表示测试塔的高度。
    输出一个整数,表示最多测试多少次。

    例如:
    输入:
    3

    程序应该输出:
    2

    解释:
    手机a从2楼扔下去,坏了,就把b手机从1楼扔;否则a手机继续3层扔下

    再例如:
    输入:
    7

    程序应该输出:
    3

    解释:
    a手机从4层扔,坏了,则下面有3层,b,c 两部手机2次足可以测出指数;
    若是没坏,手机充足,上面5,6,7 三层2次也容易测出。

    资源约定:
    峰值内存消耗(含虚拟机) < 256M
    CPU消耗 < 1000ms


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

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

    提交程序时,注意选择所期望的语言类型和编译器类型。

    ---------------------------------
    笨笨有话说:
    我觉得3个手机太难了,要是2个手机还可以考虑一下。

    歪歪有话说:
    想什么呢,你!要是1部手机还用你编程啊?那样的话只好从下往上一层一层测。

    暂时还没悟透

    可先参考:https://blog.csdn.net/belous_zxy/article/details/80543276

  • 相关阅读:
    Windows10下VirtualBox安装CentOS7网络配置:添加DNS
    Windows下LaTeX环境: SumatraPDF + notepad++/ST3
    Windows10 环境变量设置: "此环境变量太大"
    修改CMD字体后导致乱码的恢复方法
    nfs:server is not responding,still trying 原因与解决方案
    [GIT] 更新.repo目录
    linux网络栈相关
    linux mailbox模型
    虚拟机ping不通主机,主机能ping 通虚拟机问题解决
    pygame学习
  • 原文地址:https://www.cnblogs.com/Marginalin/p/12500055.html
Copyright © 2011-2022 走看看