UVA114 Simulation Wizardry
此题为模拟类型,必须认真读题,绝不能漏掉任何一个细节。
分析
解释代码中的主要部分:
-
结构体定义:
struct POINT
用于表示二维坐标,struct BUMPER
用于表示弹板的信息,包括分值和消耗。 -
pTable
数组:用于记录所有弹板的信息。数组的索引对应表面上的网格点,每个网格点上可能有一个弹板,通过指针BUMPER*
存储弹板的信息。 -
aDir
数组:表示四个方向,即向上、向右、向下、向左。 -
输入部分:程序首先从标准输入读取表面的尺寸、墙的消耗、弹板数量,然后循环读入每个弹板的坐标、分值和消耗,并将弹板信息存储到
pTable
数组中。 -
循环模拟每个球的移动:程序继续从标准输入读入每个球的起始坐标、起始方向和生命值。然后,通过一个嵌套循环来模拟每个球的移动过程。在每个时间步中,程序计算球在新位置的坐标,检查是否撞墙或撞击保险杠,根据撞击的情况更新球的分值和生命值,以及改变球的方向。循环终止条件是球的生命值小于等于 \(0\),表示球消失从表面。
-
输出:对于每个球,程序会输出球在每次撞击保险杠时得到的分值,然后将这一次撞击得到的分值累加到总分中。最后,程序输出所有球撞击保险杠得到的总分。需要注意的一些问题:
- 表面网格的坐标从左下角开始,而数组索引是从 \(0\) 开始的,因此在读入弹板和球的坐标时需要适配数组索引。
- 碰撞墙壁或保险杠时,球的方向会改变。具体地,撞墙时顺时针旋转 \(90\) 度,撞保险杠时逆时针旋转 \(90\) 度。
- 每个球在撞击保险杠或墙壁时都会消耗生命值,生命值小于等于 \(0\) 时球消失。
下面奉上代码……
AC Code
#include <iostream>
using namespace std;
struct POINT { int x; int y; };
//记录弹板信息的结构体
struct BUMPER { int nValue; int nCost; };
int main(void) {
//用二维数组记录所有弹板的信息,不存在弹板的位置为空指针
BUMPER *pTable[52][52] = {0}, *pBumper;
//按照题目指定的方向编号,设定移动偏移量
POINT ptSize, ptPos, aDir[4] = { {1, 0}, {0, 1}, {-1, 0}, {0, -1} };
int nWCost, nTotal = 0, nValue, nLife, nDir;
//输入桌面尺寸、墙的消耗、弹板数量
for (cin >> ptSize.x >> ptSize.y >> nWCost >> nTotal; nTotal-- > 0; ) {
//循环读入每个弹板的坐标、分值以及消耗,并存入数组
cin >> ptPos.x >> ptPos.y;
pBumper = new BUMPER;
cin >> pBumper->nValue >> pBumper->nCost;
//弹板的坐标是以1起始的,需适配以0起始的数组地址
pTable[ptPos.x - 1][ptPos.y - 1] = pBumper;
}
//桌面尺寸也需适配以0起始的数组地址
ptSize.x -= 1, ptSize.y -= 1;
//循环读入每个球的起始坐标,起始方向和生命值
for (nTotal = 0; cin >> ptPos.x >> ptPos.y >> nDir >> nLife;) {
//使坐标适配数组地址
--ptPos.x, --ptPos.y;
//循环移动小球,直到生命结束
for (nValue = 0; --nLife > 0; ) {
//建立新坐标变量存储移动后的值,以便移动失败时回退
POINT ptNew = {ptPos.x + aDir[nDir].x, ptPos.y + aDir[nDir].y};
//撞墙
if (ptNew.x == ptSize.x || ptNew.y == ptSize.y ||
ptNew.x < 1 || ptNew.y < 1) {
//生命值减去墙的消耗并转向
nLife -= nWCost;
nDir = (nDir + 3) % 4;
continue;
}
//碰到弹板
if ((pBumper = pTable[ptNew.x][ptNew.y]) != 0) {
//分值加上弹板的分值,生命值减去消耗并转向
nValue += pBumper->nValue;
nLife -= pBumper->nCost;
nDir = (nDir + 3) % 4;
continue;
}
//移动到空白格子
ptPos = ptNew;
}
//总分累加这一次的分值并输出当前分值
nTotal += nValue;
cout << nValue << endl;
}
//输出总分,程序结束
cout << nTotal << endl;
return 0;
}
标签:UVA114,pBumper,ptPos,分值,Wizardry,Simulation,弹板,ptNew,nDir
From: https://www.cnblogs.com/cxy-xlf-1003/p/17607450.html