2017-第八届蓝桥杯大赛个人赛省赛(软件类)真题 C大学A组

题目一览:

1.迷宫

2.跳蚱蜢

3.魔方状态

4.方格分割

5.字母组串

6.最大公共子串

7.正则问题

8.包子凑数

9.分巧克力

10.油漆面积

1.迷宫

X星球的一处迷宫游乐场建在某个小山坡上。
它是由10x10相互连通的小房间组成的。

房间的地板上写着一个很大的字母。
我们假设玩家是面朝上坡的方向站立,则:
L表示走到左边的房间,
R表示走到右边的房间,
U表示走到上坡方向的房间,
D表示走到下坡方向的房间。

X星球的居民有点懒,不愿意费力思考。
他们更喜欢玩运气类的游戏。这个游戏也是如此!

开始的时候,直升机把100名玩家放入一个个小房间内。
玩家一定要按照地上的字母移动。

迷宫地图如下:
------------
UDDLUULRUL
UURLLLRRRU
RRUURLDLRD
RUDDDDUUUU
URUDLLRRUU
DURLRLDLRL
ULLURLLRDU
RDLULLRDDD
UUDDUDUDLL
ULRDLUURRR
------------

请你计算一下,最后,有多少玩家会走出迷宫?
而不是在里边兜圈子。

请提交该整数,表示走出迷宫的玩家数目,不要填写任何多余的内容。

如果你还没明白游戏规则,可以参看一个简化的4x4迷宫的解说图:
p1.png

 思路:模拟即可。走出判定:出界;走不出判定:走到了原来走过的点。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 string s[101];
 5 bool flag, vis[11][11], Break;
 6 int Ans;
 7 
 8 void dfs(int x, int y) {
 9     if(x<0 || x>9 || y<0 || y>9) { // 走出 
10         flag = true;
11         return ;
12     }
13     if(vis[x][y]) { // 走到了走过的点 
14         Break = true;
15         return ;
16     }
17     if(Break || flag) return;
18     vis[x][y] = true; // 标记 
19     if(s[x][y] == 'U') x--; // 下一步 
20     else if(s[x][y] == 'D') x++;
21     else if(s[x][y] == 'L') y--;
22     else if(s[x][y] == 'R') y++;
23     dfs(x, y);
24 }
25 
26 int main() {
27     for(int i=0; i<10; ++i) 
28         cin >> s[i];
29     for(int i=0; i<10; ++i) {
30         for(int j=0; j<10; ++j) {
31             flag = Break = false;// 每次都要初始化 
32             memset(vis, false, sizeof(vis)); 
33             dfs(i, j);
34             if(flag) Ans++;
35         }
36     }
37     printf("%d\n", Ans);
38     return 0;
39 }
1.迷宫

答案:31

2.跳蚱蜢

如图 p1.png 所示:

有9只盘子,排成1个圆圈。
其中8只盘子内装着8只蚱蜢,有一个是空盘。
我们把这些蚱蜢顺时针编号为 1~8

每只蚱蜢都可以跳到相邻的空盘中,
也可以再用点力,越过一个相邻的蚱蜢跳到空盘中。

请你计算一下,如果要使得蚱蜢们的队形改为按照逆时针排列,
并且保持空盘的位置不变(也就是1-8换位,2-7换位,...),至少要经过多少次跳跃?

注意:要求提交的是一个整数,请不要填写任何多余内容或说明文

思路:宽搜,每次将四种跳法后的局面判重加入即可。

 1 #include <bits/stdc++.h>
 2 #include <queue> 
 3 using namespace std;
 4 
 5 char ss[1010][1010];
 6 int len;
 7 set<string> vis;
 8 
 9 struct Node {
10     string s; // 当前局面 
11     int pos, cnt; // 空格位置  到达该局面的步数 
12 };
13 
14 void bfs() {
15     queue<Node> q;
16     Node head;
17     head.pos = head.cnt = 0; head.s = "012345678"; // 初始局面 
18     q.push(head);
19     while(!q.empty()) {
20         head = q.front(); q.pop();
21         if(head.s == "087654321") { // 到达目标局面 
22             printf("Ans = %d\n", head.cnt);
23             return ;
24         }
25         for(int i=-2; i<=2; ++i) { // 四种跳法 
26             if(i == 0) continue;
27             string str = head.s;
28             int tmp = head.pos;
29             swap(str[tmp], str[(tmp+i+9)%9]);
30             Node tail;
31             if(vis.count(str) == 0) { // 当前局面之前没有 
32                 vis.insert(str);
33                 tail.s = str;
34                 tail.pos = (tmp+i+9)%9;
35                 tail.cnt = head.cnt+1;
36                 q.push(tail);
37             }
38         }
39     }
40 }
41 
42 int main() {
43     bfs();
44     return 0;
45 }
2.跳蚱蜢

答案:20

3.魔方状态

二阶魔方就是只有2层的魔方,只由8个小块组成。
如图p1.png所示。

小明很淘气,他只喜欢3种颜色,所有把家里的二阶魔方重新涂了颜色,如下:

前面:橙色
右面:绿色
上面:黄色
左面:绿色
下面:橙色
后面:黄色

请你计算一下,这样的魔方被打乱后,一共有多少种不同的状态。

如果两个状态经过魔方的整体旋转后,各个面的颜色都一致,则认为是同一状态。

请提交表示状态数的整数,不要填写任何多余内容或说明文字。

答案:229878

4.方格分割

6x6的方格,沿着格子的边线剪开成两部分。
要求这两部分的形状完全相同。

如图:p1.png, p2.png, p3.png 就是可行的分割法。

试计算:
包括这3种分法在内,一共有多少种不同的分割方法。
注意:旋转对称的属于同一种分割法。

请提交该整数,不要填写任何多余的内容或说明文字。

思路:这道题很巧妙,不按照格子搜索,搜索点,从中心点开始深搜,同时标记对称的点,当一边搜完时就是一个可行的方案。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int Ans;
 5 int u[4] = {-1, 0, 0, 1}, v[4] = {0, -1, 1, 0};
 6 bool vis[10][10];
 7 
 8 bool check(int x, int y) {
 9     if(vis[x][y]) return false; // 走过了 
10     if(x<0 || x>6) return false; // 出界 
11     if(y<0 || y>6) return false;
12     return true;
13 }
14 
15 void dfs(int x, int y) {
16     if(x==0 || x==6 || y==0 || y==6) { // 搜到边界了 
17         Ans ++;
18         return ;
19     }
20     vis[x][y] = vis[6-x][6-y] = true; // 标记
21     for(int i=0; i<4; ++i) { // 四个方向 
22         int xx = x + u[i];
23         int yy = y + v[i];
24         if(check(xx, yy)) {
25             dfs(xx, yy);
26         }
27     }
28     vis[x][y] = vis[6-x][6-y] = false; // 回溯 
29 }
30 
31 int main() {
32     memset(vis, false, sizeof(vis));
33     dfs(3, 3); // 从中心点开始搜索 
34     printf("%d\n", Ans/4); // 有重复 
35     return 0;
36 }
4.方格分割

答案:509

5.字母组串

由 A,B,C 这3个字母就可以组成许多串。
比如:"A","AB","ABC","ABA","AACBB" ....

现在,小明正在思考一个问题:
如果每个字母的个数有限定,能组成多少个已知长度的串呢?

他请好朋友来帮忙,很快得到了代码,
解决方案超级简单,然而最重要的部分却语焉不详。

请仔细分析源码,填写划线部分缺少的内容。

 1 #include <stdio.h>
 2 
 3 // a个A,b个B,c个C 字母,能组成多少个不同的长度为n的串。
 4 int f(int a, int b, int c, int n)
 5 {
 6     if(a<0 || b<0 || c<0) return 0;
 7     if(n==0) return 1; 
 8     
 9     return ______________;  // 填空
10 }
11 
12 int main()
13 {
14     printf("%d\n", f(1,1,1,2));
15     printf("%d\n", f(1,2,3,3));
16     return 0;
17 }
5.字母组串

对于上面的测试数据,小明口算的结果应该是:
6
19


注意:只填写划线部分缺少的代码,不要提交任何多余内容或说明性文字。

6.最大公共子串

7.正则问题

8.包子凑数

9.分巧克力

10.油漆面积

猜你喜欢

转载自www.cnblogs.com/Marginalin/p/12641742.html