UVA114 Simulation Wizardry
UVA114 Simulation Wizardry
此题为模拟类型,必须认真读题,绝不能漏掉任何一个细节。
分析
解释代码中的主要部分:
-
结构体定义:
struct POINT
用于表示二维坐标,struct BUMPER
用于表示弹板的信息,包括分值和消耗。 -
pTable
数组:用于记录所有弹板的信息。数组的索引对应表面上的网格点,每个网格点上可能有一个弹板,通过指针BUMPER*
存储弹板的信息。 -
aDir
数组:表示四个方向,即向上、向右、向下、向左。 -
输入部分:程序首先从标准输入读取表面的尺寸、墙的消耗、弹板数量,然后循环读入每个弹板的坐标、分值和消耗,并将弹板信息存储到
pTable
数组中。 -
循环模拟每个球的移动:程序继续从标准输入读入每个球的起始坐标、起始方向和生命值。然后,通过一个嵌套循环来模拟每个球的移动过程。在每个时间步中,程序计算球在新位置的坐标,检查是否撞墙或撞击保险杠,根据撞击的情况更新球的分值和生命值,以及改变球的方向。循环终止条件是球的生命值小于等于
,表示球消失从表面。 -
输出:对于每个球,程序会输出球在每次撞击保险杠时得到的分值,然后将这一次撞击得到的分值累加到总分中。最后,程序输出所有球撞击保险杠得到的总分。需要注意的一些问题:
- 表面网格的坐标从左下角开始,而数组索引是从
开始的,因此在读入弹板和球的坐标时需要适配数组索引。 - 碰撞墙壁或保险杠时,球的方向会改变。具体地,撞墙时顺时针旋转
度,撞保险杠时逆时针旋转 度。 - 每个球在撞击保险杠或墙壁时都会消耗生命值,生命值小于等于
时球消失。
- 表面网格的坐标从左下角开始,而数组索引是从
下面奉上代码……
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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现