蓝桥杯训练营第二周作业

1.带分数
问题描述
100 可以表示为带分数的形式:100 = 3 + 69258 / 714。
还可以表示为:100 = 82 + 3546 / 197。
注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。
类似这样的带分数,100 有 11 种表示法。
输入格式
从标准输入读入一个正整数N (N<1000*1000)
输出格式
程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!
样例输入1
100
样例输出1
11
样例输入2
105
样例输出2
6
用C语言写更合适,单层dfs 递归实现1~9的全排列 再对排列好的一串数字切分 判断是否满足条件

#include <iostream>using namespace std;const int N = 10;int target; //题目给出的目标数
int num[N]; //保存全排列的结果
bool used[N]; //生成全排列过程中标记是否使用过
int cnt; //计数,最后输出的结果//计算num数组中一段的数是多少
int calc(int l, int r){int res = 0;for(int i = l; i <= r; i++)res = res * 10 + num[i];return res;
}//生成全排列
//当全排列生成后进行分段
void dfs(int u){//用两层循环分成三段if(u == 9){for(int i = 0; i < 7; i++)for(int j = i + 1; j < 8; j++){int a = calc(0, i);int b = calc(i + 1, j);int c = calc(j + 1, 8);//注意判断条件,因为C++中除法是整除,所以要转化为加减乘来计算if(a * c + b == c * target) cnt++;}return;}//搜索模板for(int i = 1; i <= 9; i++)if(!used[i]){used[i] = true; //标记使用num[u] = i;dfs(u + 1);used[i] = false; //还原现场}
}int main(){scanf("%d", &target);dfs(0);printf("%d\n", cnt);return 0;
}

2.李白打酒
问题描述
题目描述
话说大诗人李白,一生好饮。幸好他从不开车。
一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱:
无事街上走,提壶去打酒。
逢店加一倍,遇花喝一斗。

这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。

请你计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b。则:babaabbabbabbbb 就是合理的次序。像这样的答案一共有多少呢?

num = 0
def count(a, b, c):global numif a > 0:count(a-1, b, c*2)if b > 0:count(a, b-1, c-1)if a == 0 and b == 0 and c == 1:num += 1count(5, 9, 2)
print(num)

答案为14

3.第39级台阶
问题描述
小明刚刚看完电影《第39级台阶》,离开电影院的时候,他数了数礼堂前的台阶数,恰好是39级!
站在台阶前,他突然又想着一个问题:
如果我每一步只能迈上1个或2个台阶。先迈左脚,然后左右交替,最后一步是迈右脚,也就是说一共要走偶数步。那么,上完39级台阶,有多少种不同的上法呢?

思路:这道题可以分成左右脚来写函数,各有三种情况,左脚:当上第一级台阶是可以上一步,直接上第二级台阶时也可以是一步,当上大于三级台阶是就需要加上右脚
右脚:当上第一级台阶时只能为0,因为必须先左脚上,当上第二级台阶时可以上一步,当上大于三级台阶时就需要加上右脚。
因为我们可以从39级台阶往回看,就可以用递归的方法
首先明确两个函数:

def left(n)
def right(n)

然后确定递归终止条件:

def left(n):if n == 1:  # 当剩余台阶为一个时,也就是从左脚走一步开始return 1elif n == 2:  # 当剩余台阶为两个时,也就是从左脚走两步开始  return 1def right(n):if n == 1:  # 当剩余台阶为一个时,右脚不能先走,所以为0return 0elif n == 2:return 1  # 当剩余台阶为两个时,右脚可以走一个台阶

最后缩小函数,找出等价关系式:

def left(n):if n == 1:  # 当剩余台阶为一个时,也就是从左脚走一步开始return 1elif n == 2:  # 当剩余台阶为两个时,也就是从左脚走两步开始  return 1else:return right(n-1) + reight(n-2)  # 当剩余台阶大于3时,就要换脚,这时候你可能走完了两个台阶也可能走完了一个台阶,所有两种方法要加起来传给另一只脚def right(n):if n == 1:  # 当剩余台阶为一个时,右脚不能先走,所以为0return 0elif n == 2:return 1  # 当剩余台阶为两个时,右脚可以走一个台阶else:return left(n-1) + left(n-2)
print(right(39))

4.穿越雷区
问题描述
已知的地图是一个方阵,上面用字母标出了A,B区,其它区都标了正号或负号分别表示正负能量辐射区。
例如:
A + - + -

B + - + -

坦克车只能水平或垂直方向上移动到相邻的区。
数据格式要求:
输入第一行是一个整数n,表示方阵的大小, 4<=n<100
接下来是n行,每行有n个数据,可能是A,B,+,-中的某一个,中间用空格分开。
A,B都只出现一次。
要求输出一个整数,表示坦克从A区到B区的最少移动步数。
如果没有方案,则输出-1
例如:
用户输入:
5
A + - + -

B + - + -
则程序应该输出:
10

#include <bits/stdc++.h>//万能头文件
using namespace std;char Map[101][101]; //地图数组
bool Vis[101][101]; //标记数组 标记是否走过
int Next[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; //方向数组 遍历方向typedef struct node { //定义结构体数组,便于操作调用 包含坐标,步数,符号int x, y, step;char flag;
} node;
node n[10001]; //BFS数组一般是m*m,再开大一点int main() {int m;cin >> m;getchar(); //吃掉回车int head, tail, x, y, tx, ty;for (int i = 1; i <= m; i++) {for (int j = 1; j <= m; j++) {scanf("%c", &Map[i][j]);if (Map[i][j] == 'A') { //记下起点位置的坐标x = i, y = j;}getchar(); //吃掉空格和回车}}head = tail = 1; //初始化 BFS可以理解为一个队列,头和尾n[head].x = x;n[head].y = y;n[head].step = 0;n[head].flag = ' ';Vis[x][y] = 1; //标记起点位置为走过了tail++;while (head < tail) { //BFS核心for (int i = 0; i < 4; i++) { //遍历4个方向tx = n[head].x + Next[i][0];ty = n[head].y + Next[i][1];if (tx > m || ty > m || tx < 1 || ty < 1) //出边界continue;if (Vis[tx][ty] == 0 && n[head].flag != Map[tx][ty]) { //没走过且符合+-Vis[tx][ty] = 1;n[tail].flag = Map[tx][ty];n[tail].x = tx;n[tail].y = ty;n[tail].step = n[head].step + 1;tail++;}}if (n[head].flag == 'B') { //走到终点cout << n[head].step << endl;return 0;}head++;}cout << "-1"; //走不到终点return 0;
}

5.迷宫
问题描述
下图给出了一个迷宫的平面图,其中标记为 1 的为障碍,标记为 0 的为可 以通行的地方。

010000
000100
001001
110000

迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个位置走到这 个它的上、下、左、右四个方向之一。 对于上面的迷宫,从入口开始,可以按DRRURRDDDR 的顺序通过迷宫, 一共 10 步。其中 D、U、L、R 分别表示向下、向上、向左、向右走。 对于下面这个更复杂的迷宫(30 行 50 列),请找出一种通过迷宫的方式, 其使用的步数最少,在步数最少的前提下,请找出字典序最小的一个作为答案。 请注意在字典序中D<L<R<U。(如果你把以下文字复制到文本文件中,请务 必检查复制的内容是否与文档中的一致。在试题目录下有一个文件 maze.txt, 内容与下面的文本相同)

理解应该不难,就是步骤有些繁琐

#include <iostream>
#include <stdio.h>
#include <string>
#include <queue>
using namespace std;
const int M = 30; const int N = 50;
char maze[M][N];
int flag[M][N] = {0};
int path[M][N] = {0};
int dire[4][2] = {1, 0,0,-1,0, 1,-1,0
};
string dir = "DLRU";void bfs(){queue< pair<int, int> > q;q.push(make_pair(0, 0));maze[0][0] = 1;while(!q.empty()){int x = q.front().first;int y = q.front().second;q.pop();for(int i = 0; i < 4; i++){int dx = x + dire[i][0];int dy = y + dire[i][1];if(dx > 29 || dx < 0 || dy > 49 || dy < 0) continue;if(flag[dx][dy] == 0 && maze[dx][dy] == '0'){q.push(make_pair(dx, dy));flag[dx][dy] = 1;path[dx][dy] = i;//direction of last step}    }   }
}
void back(int x, int y){if(x != 0 || y != 0){int i = path[x][y];back(x - dire[i][0], y - dire[i][1]);cout << dir[i];   }
}
int main(){freopen("1.txt", "r", stdin);for(int i = 0; i < N; i++)cin >> maze[i];fclose(stdin);bfs();cout << "over..." << endl;back(29, 49);return 0;
}

6.跳马
问题描述
中国象棋半张棋盘如图1所示。马自左下角(0,0)向右上角(m,n)跳。规定只能往右跳,不准往左跳。比如图1中所示为一种跳行路线,并将路径总数打印出来。

输入格式:
只有一行:两个数n,m
输出格式:
只有一个数:总方案数total。

#include <cstdio>
int n , m ,ans ;
int dx[4] = {1,2,2,1} ;
int dy[4] = {2,1,-1,-2} ;
void dfs(int x ,int y)
{if(x == m && y == n){ans ++ ;}int i ;int tx = 0 ;int ty = 0 ;for (i = 0 ; i< 4 ;i++){tx = x + dx[i] ;ty = y + dy[i] ;if(tx >m  || tx <0 || ty >n || ty<0)continue ;else{dfs(tx,ty);}}}
int main()
{scanf("%d%d",&n,&m);dfs(0,0);printf("%d",ans);return 0 ;
}

7.路径之谜
问题描述
小明冒充X星球的骑士,进入了一个奇怪的城堡。
城堡里边什么都没有,只有方形石头铺成的地面。

假设城堡地面是 n x n 个方格。【如图1.png】所示。

按习俗,骑士要从西北角走到东南角。
可以横向或纵向移动,但不能斜着走,也不能跳跃。
每走到一个新方格,就要向正北方和正西方各射一箭。
(城堡的西墙和北墙内各有 n 个靶子)

同一个方格只允许经过一次。但不必做完所有的方格。
如果只给出靶子上箭的数目,你能推断出骑士的行走路线吗?
有时是可以的,比如图1.png中的例子。

本题的要求就是已知箭靶数字,求骑士的行走路径(测试数据保证路径唯一)

输入:
第一行一个整数N(0<N<20),表示地面有 N x N 个方格
第二行N个整数,空格分开,表示北边的箭靶上的数字(自西向东)
第三行N个整数,空格分开,表示西边的箭靶上的数字(自北向南)

输出:
一行若干个整数,表示骑士路径。

为了方便表示,我们约定每个小格子用一个数字代表,从西北角开始编号: 0,1,2,3…
比如,图1.png中的方块编号为:

0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15

示例:
用户输入:
4
2 4 3 4
4 3 3 3

程序应该输出:
0 4 5 1 2 3 7 11 10 9 13 14 15

path = [0 for _ in range(401)]# 记录走过的点
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]# 我们的移动
cntx = [0 for _ in range(21)]
cnty = [0 for _ in range(21)]# 记录箭的数量
maps = [[False for _ in range(21)]for _ in range(21)]# 用于判断是否走过
sun = False
tot = 0# 箭的总数def check():# 判断是否完成,如果有一个为零,就不能往下走了for i in range(0, n):if cntx[i] != 0 or cnty[i] != 0:return Falsereturn Truedef dfs(x, y, num):global sunpath[num] = y *n + x # 坐标点maps[x][y] = True cntx[x] -= 1 # 我们这步走过来拔剑cnty[y] -= 1 # 我们这步走过拔剑if x == n and y == n and check():sun = True# 完成走了returnfor i in range(4):x1 = x + dx[i]y1 = y + dy[i]if not sun and not maps[x1][y1] and 0 <= x1 < n and 0 <= y1 < n:if cntx[x1] > 0 and cnty[y1] > 0:dfs(x1, y1, num+1)maps[x1][y1] = False# 回溯,至关重要cntx[x1] += 1cnty[y1] += 1n = int(input())
for i in range(0, n):cntx[i] = int(input())tot += cntx[i]
for i in range(0, n):cnty[i] = int(input())tot += cnty[i]
dfs(0, 0, 0)
print(path[:tot//2])# 走了箭的一半的数量应该没毛病

8.未名湖边的烦恼
问题描述
每年冬天,北大未名湖上都是滑冰的好地方。北大体育组准备了许多冰鞋,可是人太多了,每天下午收工后,常常一双冰鞋都不剩。
  每天早上,租鞋窗口都会排起长龙,假设有还鞋的m个,有需要租鞋的n个。现在的问题是,这些人有多少种排法,可以避免出现体育组没有冰鞋可租的尴尬场面。(两个同样需求的人(比如都是租鞋或都是还鞋)交换位置是同一种排法)
输入格式
  两个整数,表示m和n
输出格式
  一个整数,表示队伍的排法的方案数。
样例输入
3 2
样例输出
5
数据规模和约定
  m,n∈[0,18]
  
用递归的方法写,一点毛病没有

#include<stdio.h>
#include<stdlib.h>
int count = 0;//记录有多少种排法
int fun(int m, int n, int a)//a为租鞋窗口有多少鞋可租
{if (m < 0 || n < 0 || a < 0)return NULL;if (m == 0 && n == 0)count++;fun(m - 1, n, a + 1);//还鞋 fun(m, n - 1, a - 1);//租鞋 return count;
}
int main()
{int m, n;printf("请依次输入还鞋和租鞋的人数\n");scanf_s("%d%d", &m, &n);printf("%d\n", fun(m, n, 0));system("pause");return 0;
}

9.大臣的旅费
问题描述
很久以前,T王国空前繁荣。为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市。
为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者通过其他大城市间接到达。同时,如果不重复经过大城市,从首都到达每个大城市的方案都是唯一的。
J是T国重要大臣,他巡查于各大城市之间,体察民情。所以,从一个城市马不停蹄地到另一个城市成了J最常做的事情。他有一个钱袋,用于存放往来城市间的路费。
聪明的J发现,如果不在某个城市停下来修整,在连续行进过程中,他所花的路费与他已走过的距离有关,在走第x千米到第x+1千米这一千米中(x是整数),他花费的路费是x+10这么多。也就是说走1千米花费11,走2千米要花费23。
J大臣想知道:他从某一个城市出发,中间不休息,到达另一个城市,所有可能花费的路费中最多是多少呢?
输入格式
输入的第一行包含一个整数n,表示包括首都在内的T王国的城市数
城市从1开始依次编号,1号城市为首都。
接下来n-1行,描述T国的高速路(T国的高速路一定是n-1条)
每行三个整数Pi, Qi, Di,表示城市Pi和城市Qi之间有一条高速路,长度为Di千米。
输出格式
输出一个整数,表示大臣J最多花费的路费是多少。

cnt=0
node=0
def dfs(v,k):   #进行dfs搜索global cntglobal nodeglobal visif k>cnt:cnt=knode=vfor i in range(len(E[v])):if vis[E[v][i][0]]==False: #没访问过的点都进行一次dfsvis[E[v][i][0]]=True #进行标记dfs(E[v][i][0],k+E[v][i][1])vis[E[v][i][0]]=False #回溯
n=int(input())
E=[[]for i in range(n+1)]
vis=[False for i in range(n+1)]
for i in range(n-1):x,y,z=map(int,input().split())E[x].append((y,z))E[y].append((x,z)) #将各个点进行连接,用列表数组的方式进行
vis[1]=True
dfs(1,0)  #找到距离1最远的点node
vis[1]=False
cnt=0
vis[node]=True
dfs(node,0)  #从node出发,找到最远的点,就是所要求的最远距离
res=0
for i in range(1,cnt+1):res+=i+10
print(res)

10.2n皇后问题
问题描述
定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后
和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两
个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8。

Input
输入的第一行为一个整数n,表示棋盘的大小。
接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,
如果一个整数为0,表示对应的位置不可以放皇后。

Output
输出一个整数,表示总共有多少种放法。

Sample Input
No.1
4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1

No.2
4
1 0 1 1
1 1 1 1
1 1 1 1
1 1 1 1
Sample Output

No.1
2

No.2
0

思路

先在index放置黑皇后
递归,在index+1行放置黑皇后
递归到底,index == n ,这个时候说明黑皇后已经全部放置完毕(一种情况),这个时候再开始第二次dfs2(0),这个时候是放置白皇后,白皇后也放置完毕以后,一个解就找到了。

from collections import defaultdictn = int(input())
board = []
for i in range(n):board.append(input().split())
col1 = defaultdict(bool)
dia11 = defaultdict(bool)
dia21 = defaultdict(bool)
col2 = defaultdict(bool)
dia12 = defaultdict(bool)
dia22 = defaultdict(bool)
count = 0def dfs2(index):global countif index == n:count += 1return# 在第index行放置黑皇后for j in range(n):if not col2[j] and not dia12[index + j] and not dia22[index - j] \and board[index][j] == "1":col2[j] = Truedia12[index + j] = Truedia22[index - j] = Trueboard[index][j] = "0"dfs2(index + 1)col2[j] = Falsedia12[index + j] = Falsedia22[index - j] = Falseboard[index][j] = "1"return 0def dfs1(index):if n <= 0:return 0if index == n:dfs2(0)return# 在第index行放置黑皇后for j in range(n):if not col1[j] and not dia11[index + j] and not dia21[index - j] \and board[index][j] == "1":col1[j] = Truedia11[index + j] = Truedia21[index - j] = Trueboard[index][j] = "0"dfs1(index + 1)col1[j] = Falsedia11[index + j] = Falsedia21[index - j] = Falseboard[index][j] = "1"return 0dfs1(0)
print(count)

谢谢观看

#蓝桥杯真题【思特奇杯·云上蓝桥-算法集训营】第2周相关推荐

  1. 【思特奇杯·云上蓝桥-算法集训营】第二周

    问题1 带分数 问题描述 100 可以表示为带分数的形式:100 = 3 + 69258 / 714. 还可以表示为:100 = 82 + 3546 / 197. 注意特征:带分数中,数字1~9分别出 ...

  2. 【思特奇杯·云上蓝桥-算法集训营】第一周

    跑步训练 问题描述 小明要做一个跑步训练,初始时,小明充满体力,体力值计为 10000. 如果小明跑步,每分钟损耗 600 的体力. 如果小明休息,每分钟增加 300 的体力. 体力的损耗和增加都是 ...

  3. 【思特齐杯.云上蓝桥-算法集训营】第二周

    1. 带分数 import java.util.Scanner;   public class 带分数 {       /**      * n= a + b/c      */     public ...

  4. c语言六角填数蓝桥杯答案,六角填数(全排列)蓝桥杯真题

    六角填数(全排列)蓝桥杯真题 六角填数(全排列)蓝桥杯真题 如图所示六角形中填入1-12的数字,使每条直线上的数字和相等,图中已经填好了3个数字,请你计算*号数字是多少 蓝桥杯老套路,经常这样考全排列 ...

  5. 思特奇杯·云上蓝桥 -算法 集训营第二周

    思特奇杯·云上蓝桥 -算法 集训营第二周 1. 带分数 题目描述 解法一 解题思路 python代码 2. 李白打酒 题目描述 解法一 解题思路 python代码 3. 第 39 级台阶 题目描述 解 ...

  6. 第五届蓝桥杯真题解析【JavaC组】

    第五届蓝桥杯真题解析[JavaC组] 业精于勤,荒于嬉:行成于思,毁于随.--韩愈 文章目录 ***第五届蓝桥杯真题解析[JavaC组]*** 前言 A:猜年龄 B:等额本金 C:猜字母 D:大衍数列 ...

  7. python解答蓝桥杯真题2 猜年龄 美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学。他曾在19351936年应邀来中国清华大学讲学。。。

    python解答蓝桥杯真题2 猜年龄 美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学.他曾在1935~1936年应邀来中国清华大学讲学... 问题描述 全排列模板: 美国数学家维纳(N. ...

  8. 【蓝桥杯真题】16天冲刺 Python

    距离比赛很快了,希望和我一起准备的PY党能更加熟练的掌握Python! 1.距离和(模拟赛填空题) 问题描述: 两个字母之间的距离定义为它们在字母表中位置的距离.例如 A和 C 的距离为 2,L 和  ...

  9. 蓝桥杯真题:三羊献瑞

    蓝桥杯真题:三羊献瑞 观查下面的加法算式: 其中相同的汉字代表相同的数字,不同的汉字代表不同的数字. 请你填写"三羊献瑞"所代表的4位数字(答案唯一),不要填写任何多余内容. 分析 ...

  10. # 2014年蓝桥杯真题CC++B组

    2014年蓝桥杯真题C/C++B组 1.啤酒和饮料 题目描述 啤酒每罐2.3元,饮料每罐1.9元,小明买了若干啤酒和饮料,一共花了82.3元. 我们还知道她买的啤酒比饮料的数量多,请你计算他买了几罐啤 ...

最新文章

  1. C语言位操作--判断整数是否为2的幂
  2. 【BOM is recursion】BOM 是递归的
  3. IDE硬盘,SATA硬盘,SCSI硬盘有什么区别
  4. anaconda如何做python笔记_python笔记
  5. TinyML与Tensor Flow Lite的关系
  6. L1-008 求整数段和 (10 分)—团体程序设计天梯赛
  7. NLP领域最优秀的8个预训练模型(附开源地址)
  8. 平台: pSeries AIX 4.3 AIX 5L
  9. 30个Python小游戏,上班摸鱼我能玩一天【内附源码】
  10. 关于计算机软件系统的知识,会计电算化知识点:计算机软件系统
  11. PHP 简单开发实例
  12. pythonsorted函数cmp_python3中sorted函数里cmp参数改变详解
  13. 创建室内导航地图的9个步骤
  14. PV操作经典例题——和尚打水
  15. 2021年全球及中国酒店行业发展现状及竞争格局分析,全球酒店行业景气度大幅回暖「图」
  16. 为什么拉格朗日对偶函数一定是凹函数(逐点下确界)
  17. 微信公众号支付从前端到后台(小白教程)
  18. 2022年茶艺师(中级)考试模拟100题模拟考试平台操作
  19. SIMULIA现实仿真解决方案 SIMULIA仿真模拟应用程序
  20. 计算机中的英语六级作文万能模板,英语六级作文的通用万能模板

热门文章

  1. ECharts官方教程(四)【个性化图表的样式】
  2. 华为机试二星题--机器人走迷宫
  3. office2016、office365和office其它版本JH
  4. 使el-input失焦
  5. Enigma Sim-英格玛密码机模拟器
  6. 软件测试面试题-那些让我印象深刻的bug
  7. 无限纷争怎么看以前的服务器,无限纷争怎么切换角色 无限纷争切换角色方法...
  8. 何为ISM频段?ISM频段主要频率有哪些? 1
  9. java入门篇(21)File类
  10. 台州银行笔试考什么_【精选】台州银行历年真题笔试题面试题大全.pdf