USACO备考冲刺必刷题 | P2958 Papaya Jungle

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

附上汇总贴:USACO备考冲刺必刷题 | 汇总-CSDN博客


【题目描述】

Bessie不小心游荡出Farmer John的田地,而走进了相邻的农民的地里。她举起一个木瓜,木瓜对奶牛来说可是不可多得得美味。这个木瓜林像一般的威斯康星州的田地一样被分割成一个R行C列的网格(1 <= R <= 40, 1 <= C <= 40)。Bessie可以从一个格沿着一条跟X轴或Y轴平行的直线走到邻接的另一个格。Bessie发现一开始她自己在木瓜林的(1,1),也就是第一行第一列慢悠悠地咀嚼着木瓜。

Bessie总是用她最信赖地双筒望远镜去数每一个邻接的格里挂着的木瓜的数目。然后她就游荡到那个有最多没有被吃掉的木瓜的邻接的格子(保证这样的格子只有一个)。

按照这种移动方法,最终Bessie总是会在(R,C)停止然后吃掉那里的木瓜。

给定这个木瓜林的大小及每个格的木瓜数F_ij(1 <= F_ij <= 100), 要求Bessie一共吃了多少个木瓜。

【输入】

  • Line 1: Two space-separated integers: R and C
  • Lines 2..R+1: Line i+1 describes row i of the jungle with C

space-separated integers that tell how many fruit are in each square: F_i1, F_i2, ..., F_iC

【输出】

  • Line 1: A single integer that is the total number of papayas that Bessie eats by the time she finishes off the papayas at the barn in the lower right corner at coordinate (R,C).

【输入样例】

3 4 
3 3 4 5 
4 5 3 2 
1 7 4 2

【输出样例】

39

【代码详解】

USACO备考冲刺必刷题 | P2958 Papaya Jungle_第1张图片

#include 
using namespace std;
int r, c, a[45][45], vis[45][45], sum=0;
int dx[4]={-1,1,0,0}, dy[4]={0,0,-1,1};
struct node {
    int x, y;
};
int main()
{
    cin >> r >> c;  // 输入r和c
    for (int i=1; i<=r; i++) {  // 遍历r行和c列,输入每个格子的木瓜数量
        for (int j=1; j<=c; j++) {
            cin >> a[i][j];
        }
    }
    queue q;  // 定义队列
    node tp = {1, 1};  // 将左上角压入队列中
    q.push(tp); 
    vis[1][1]=1;  // 修改当前格子vis为1
    sum += a[1][1];  // 将该格子的木瓜数量加起来
    while (!q.empty()) {  // BFS模板
        tp = q.front(); 
        q.pop();
        int xx, yy, xt, yt, maxn=-1e9;
        for (int i=0; i<4; i++) {  // 上下左右分别遍历
            xx = tp.x+dx[i], yy = tp.y+dy[i];
            if (xx<1||xx>r||yy<1||yy>c||vis[xx][yy]==1||a[xx][yy]==0) continue;  // 如果坐标越界或vis为1或该格子数量为0,则继续循环
            if (a[xx][yy]>maxn) {  // 使用擂台法找到四个方向中最多的没被吃掉的木瓜数,并记录其坐标
                maxn = a[xx][yy];
                xt = xx;
                yt = yy;
            }
        }
        sum += a[xt][yt];  // 确认下一次移动的格子后,将下一个格子的木瓜数加到sum中
        if (xt==r && yt==c) break;  // 当移动到(r,c),退出循环
        node t = {xt, yt};  // 将下一个格子压入队列中
        q.push(t);
        vis[xt][yt] = 1;  // 并将下一个格子的vis修改为1
    }
    cout << sum << endl;  // 输出sum
    return 0;
}

【运行结果】

3 4 
3 3 4 5
4 5 3 2
1 7 4 2
39

你可能感兴趣的:(算法,数据结构,图论)