1 条题解

  • 0
    @ 2025-4-10 16:49:56

    说明

    该程序模拟了一个简化版的弹球机游戏。弹球在一个网格平面上移动,撞击缓冲器和墙壁后会反弹并消耗寿命,同时根据撞击的物体获得或失去分数。程序需要处理多个球的发射,计算每个球的得分以及所有球的总分。

    算法标签

    • 模拟
    • 网格处理
    • 状态机

    解题思路

    1. 问题分析:弹球在网格上移动,每次移动一个格子,方向可以是上、下、左、右。球撞击缓冲器或墙壁后会顺时针旋转90度,并消耗一定的寿命。撞击缓冲器会获得分数,撞击墙壁仅消耗寿命。
    2. 输入处理:读取网格大小、墙壁撞击成本、缓冲器信息以及多个球的初始状态。
    3. 模拟过程:对于每个球,根据其初始位置和方向,逐步移动直到寿命耗尽。每次移动后检查是否撞击障碍物,并更新方向、寿命和分数。
    4. 输出结果:每个球的得分以及所有球的总分。

    分析

    • 网格表示:使用二维数组表示网格,标记墙壁和缓冲器的位置。
    • 球的移动:根据当前方向计算下一步的位置,检查是否为障碍物。
    • 撞击处理
      • 墙壁:顺时针旋转方向并消耗寿命。
      • 缓冲器:顺时针旋转方向,获得分数并消耗寿命。
    • 寿命管理:每次移动或撞击都会减少寿命,寿命耗尽时球消失。

    实现步骤

    1. 初始化网格:读取网格大小,标记边缘为墙壁。
    2. 读取缓冲器信息:存储缓冲器的位置、分值和成本。
    3. 处理每个球
      • 初始化球的位置、方向、寿命和分数。
      • 模拟移动过程,直到寿命耗尽:
        • 计算下一步位置。
        • 检查是否为墙壁或缓冲器,处理撞击。
        • 更新位置、方向、寿命和分数。
    4. 输出结果:每个球的得分和总分。

    代码解释

    • 数据结构
      • grid:二维数组,标记网格类型(墙壁、缓冲器或空地)。
      • bumpers:二维数组,存储缓冲器的分值和成本。
      • ball:结构体,存储球的当前位置、方向、寿命和分数。
    • 方向处理:使用偏移数组offset表示四个方向的移动增量。
    • 模拟循环
      • 每次移动减少寿命。
      • 检查下一步位置是否为障碍物,处理撞击逻辑。
      • 更新球的状态。
    • 输入输出
      • 读取输入参数和球的信息。
      • 输出每个球的得分和总分。

    该程序通过精确的状态管理和模拟步骤,高效地模拟了弹球机的行为,并正确计算了每个球的得分和总分。

    代码

     
    #include <iostream>
     
    using namespace std;
     
    #define MAXN 55
     
    #define GRID 0
    #define OBSTACLE 1
    #define WALL 3
     
    #define RIGHT 0
    #define UP 1
    #define LEFT 2
    #define DOWN 3
     
    struct obstacle
    {
    	int value, cost;
    };
     
    struct ball
    {
    	int x, y, direction, lifetime, points;
    };
     
    ball pinball;
    obstacle bumpers[MAXN][MAXN];
    int grid[MAXN][MAXN], gridWidth, gridHeight, costHitWall;
    int offset[4][2] = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };
     
    void ballStatus(void)
    {
    	cout << pinball.x << " " << pinball.y << " " << pinball.direction;
    	cout << " " << pinball.lifetime << " " << pinball.points << endl;
    }
     
    void play(void)
    {
    	int newX, newY;
    	
    	while (pinball.lifetime > 0)
    	{
    		// ballStatus();
     
    		pinball.lifetime--;
    		newX = pinball.x + offset[pinball.direction][0];
    		newY = pinball.y + offset[pinball.direction][1];
     
    		if (grid[newY][newX] == WALL)
    		{
    			if (newY == gridHeight && pinball.direction == UP ||
    				newY == 1 && pinball.direction == DOWN ||
    				newX == gridWidth && pinball.direction == RIGHT ||
    				newX == 1 && pinball.direction == LEFT)
    			{
    				pinball.direction--;
    				if (pinball.direction < 0)
    					pinball.direction += 4;
    				pinball.lifetime -= costHitWall;	
    			}			
    		}
    		else if (grid[newY][newX] == OBSTACLE)
    		{
    			pinball.direction--;
    			if (pinball.direction < 0)
    				pinball.direction += 4;
    			if (pinball.lifetime > 0)
    			{
    				pinball.points += bumpers[newY][newX].value;
    				pinball.lifetime -= bumpers[newY][newX].cost;
    			}
    		}
    		else
    		{
    			pinball.x = newX;
    			pinball.y = newY;
    		}
    	}
    }
     
    int main (int argc, char const* argv[])
    {
    	int totalPoints = 0, numberBumpers, tmpX, tmpY;
     
    	cin >> gridWidth >> gridHeight;
    	cin >> costHitWall;
    	for (int i = 1; i <= gridHeight; i++)
    		for (int j = 1; j <= gridWidth; j++)
    			if (i == 1 || j == 1 || i == gridHeight || j == gridWidth)
    				grid[i][j] = WALL;
    			else
    				grid[i][j] = GRID;
     
    	cin >> numberBumpers;
    	for (int i = 1; i <= numberBumpers; i++)
    	{
    		cin >> tmpX >> tmpY;
    		grid[tmpY][tmpX] = OBSTACLE;
    		cin >> bumpers[tmpY][tmpX].value;
    		cin >> bumpers[tmpY][tmpX].cost;
    	}
     
    	while (cin >> pinball.x)
    	{
    		cin >> pinball.y >> pinball.direction >> pinball.lifetime;
    		pinball.points = 0;
    		
    		play();
    	
    		totalPoints += pinball.points;
    		cout << pinball.points << endl;
    	}
     
    	cout << totalPoints << endl;
     
    	return 0;
    }
    • 1

    信息

    ID
    217
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者