USACO历年青铜组真题解析 | 2021年12月Walking Home

学习C++从娃娃抓起!记录下USACO(美国信息学奥赛)备考青铜组别比赛学习过程中的题目,记录每一个瞬间。

附上汇总贴:USACO历年青铜组真题解析 | 汇总-CSDN博客


【题目描述】

奶牛 Bessie 正准备从她最喜爱的草地回到她的牛棚。

农场位于一个 N×N 的方阵上(2≤N≤50),其中她的草地在左上角,牛棚在右下角。Bessie 想要尽快回家,所以她只会向下或向右走。有些地方有草堆(haybale),Bessie 无法穿过;她必须绕过它们。

Bessie 今天感到有些疲倦,所以她希望改变她的行走方向至多 K 次(1≤K≤3)。

Bessie 有多少条不同的从她最爱的草地回到牛棚的路线?如果一条路线中 Bessie 经过了某个方格而另一条路线中没有,则认为这两条路线不同。

【输入】

每个测试用例的输入包含 T 个子测试用例,每个子测试用例描述了一个不同的农场,并且必须全部回答正确才能通过整个测试用例。输入的第一行包含 T(1≤T≤50)。每一个子测试用例如下。

每个子测试用例的第一行包含 N 和 K

以下 N 行每行包含一个长为 N 的字符串。每个字符为 ..,如果这一格是空的,或 HH,如果这一格中有草堆。输入保证农场的左上角和右下角没有草堆。

【输出】

输出 T 行,第 i 行包含在第 i 个子测试用例中 Bessie 可以选择的不同的路线数量。

【输入样例】

7
3 1
...
...
...
3 2
...
...
...
3 3
...
...
...
3 3
...
.H.
...
3 2
.HH
HHH
HH.
3 3
.H.
H..
...
4 3
...H
.H..
....
H...

【输出样例】

2
4
6
2
0
0
6

【代码详解】

#include <bits/stdc++.h>
using namespace std;
int t, n, k;
int path[2500];
char a[55][55];
int dx[2]={0,1}, dy[2]={1,0};  // 定义向右和向下的偏离坐标
struct node {  // 定义结构体,包含x、y坐标,上一次的方向,以及调整次数step
    int x, y, d, step;
};
int main()
{
    cin >> t;  // 输入t
    while (t--) {  // 遍历t次询问
        cin >> n >> k;  // 输入n和k
        for (int i=1; i<=n; i++) {  // 记录n*n矩阵
            for (int j=1; j<=n; j++) {
                cin >> a[i][j];
            }
        }
        queue<node> q;  // 定义队列
        node tp = {1, 1, -1, 0};  // 定义队头
        q.push(tp);  // 压入队列中
        int ans=0;  // 每轮询问初始化路线数量为0
        while (!q.empty()) {  // 当队列不为空
            tp = q.front();  // 取出队头
            q.pop();
            if (tp.step>k) {  // 剪枝:如果队头的调整次数大于k了,则继续下次循环
                continue;
            }
            if (tp.x==n && tp.y==n) {  // 如果队头坐标已经到达[n,n]
                if (tp.step<=k) {  // 如果次数调整次数小于等于k(肯定满足,因为上面特判了不满足)
                    ans++;  // 路线数量加1
                }
                continue;  // 继续下次循环
            }
            for (int i=0; i<2; i++) {  // 分别计算向右和向下的路线
                int xx=tp.x+dx[i], yy=tp.y+dy[i];  // 定义偏移后的坐标
                if (xx<1 || xx>n || yy<1 || yy>n || a[xx][yy]=='H') continue;  // 如果坐标越界或者遇到'H',则继续下次循环
                node t;  // 定义即将压入队列的t
                if (tp.d == -1) {  // 如果是队头坐标[1,1]
                    t = {xx, yy, i, 0};  // 则调整次数为0
                } else if (tp.d != i) {  // 否则,只要即将要调整的方向与上一次过来的方向不一致
                    t = {xx, yy, i, tp.step+1};  // 调整次数加1
                } else {  // 调整方向与上次过来的方向一致
                    t = {xx, yy, i, tp.step};  // 调整次数还是上次的调整次数
                }
                if (t.step>k) break;  // 剪枝:如果此时t的调整次数大于k,就不用再继续了
                q.push(t);  // 将t压入队列中
            }
        }
        cout << ans << endl;  // 打印路线总数
    }
    
    return 0;
}

【运行结果】

7
3 1
...
...
...
2
3 2
...
...
...
4
3 3
...
...
...
6
3 3
...
.H.
...
2
3 2
.HH
HHH
HH.
0
3 3
.H.
H..
...
0
4 3
...H
.H..
....
H...
6
  • 15
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: USACO 202112是美国计算机奥林匹克竞赛的一次比赛,是为了选拔美国高中生中最优秀的计算机科学家而举办的。比赛包括四个不同难度级别的编程题目,参赛者需要在规定时间内完成这些题目。这次比赛的题目难度较高,需要参赛者具备较强的编程能力和算法思维能力。 ### 回答2: usaco是一个很受欢迎的美国高中生和大学生参加的计算机竞赛,每会有四场不同的赛事,分为铜组、银组、金组和白银组等4个不同级别。202112的usaco比赛题目难度中等,共4道算法题,主要涉及搜索算法、贪心算法、动态规划和图论算法等方面内容。 题目一是“Convenience Store”,给定一个城市地图,其中包含n个建筑,每个建筑位置有xy坐标,建筑之间可能有道路连通,每个建筑中包含一个便利店和售货员,售货员需要把货物直接送到顾客的门口并统计物资,问售货员需要访问哪些建筑才能完成任务。 题目二是“Longest Path Game”,给定一个有向无环图和起点和终点,每次可以走向图中指向该点的其他点,每走一步需要支付一定的代价,问从起点到终点最少需要支付多少代价并给出最少花费路径。 题目三是“Escape”,给定一个大小为n*m的迷宫,其中包含空地和只能通过特殊方式通过的障碍物,新增一个道具可以消除障碍物,在指定时间内到达终点即可获胜,问是否存在可行解。 题目四是“New Year Travel”,给定一个n个城市构成的圆环和m条单向道路,初次n个城市顺时针排列,经过m次之后重排该圆环,问是否存在一条路径可以在经过圆环的最小路程的前提下遍历所有的城市。 ### 回答3: USACO 2021 12是一次由美国计算机科学奥林匹克联赛(USACO)组织的编程竞赛。USACO是美国高中生最具影响力的计算机竞赛之一,每分为四个季度,包含铜组、银组、金组和白金组,涵盖了算法设计、数据结构、图论、搜索、动态规划、计算几何、图像处理等多个领域和真实场景。 本场比赛共有铜组、银组和金组三个组别,其中铜组和银组为在线比赛,金组为24小时比赛。比赛难度较高且时间较紧,需要选手在有限时间内完成一系列复杂的程序设计题目。在比赛期间,选手需要具备良好的分析问题、设计算法和编写程序的能力,同时还需要有过硬的数学基础、英语阅读理解能力和编程实践经验。 对于铜组选手来说,需要能够熟练使用基本算法数据结构来解决题目,如模拟、暴力搜索、递推等;对于银组选手,则需要有更深入的算法思考和程序实现能力,如分治、贪心、二分、动态规划等;而针对金组选手,需要更高的算法挑战和程序优化能力,如图论、网络流、计算几何等。 此次USACO 2021 12比赛题目难度较大,需要选手们具备扎实的算法基础和良好的程序设计习惯。要想在比赛中取得好成绩,需要选手们克服紧张心理,在比赛前加强对算法知识和代码实践的学习,时刻保持冷静,清晰思路,在有限时间内充分展现自己的编程才能和思维能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值