P1563 玩具谜题 题解

题目描述:
小南有一套可爱的玩具小人, 它们各有不同的职业。有一天, 这些玩具小人把小南的眼镜藏了起来。 小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外。如下图:这时singersinger告诉小南一个谜題: “眼镜藏在我左数第3个玩具小人的右数第11个玩具小人的左数第22个玩具小人那里。 ”小南发现, 这个谜题中玩具小人的朝向非常关键, 因为朝内和朝外的玩具小人的左右方向是相反的: 面朝圈内的玩具小人, 它的左边是顺时针方向, 右边是逆时针方向; 而面向圈外的玩具小人, 它的左边是逆时针方向, 右边是顺时针方向。小南一边艰难地辨认着玩具小人, 一边数着:singersinger朝内, 左数第33个是archerarcher。archerarcher朝外,右数第11个是thinkerthinker。thinkerthinker朝外, 左数第22个是writewriter。所以眼镜藏在writerwriter这里!虽然成功找回了眼镜, 但小南并没有放心。 如果下次有更多的玩具小人藏他的眼镜, 或是谜題的长度更长, 他可能就无法找到眼镜了 。 所以小南希望你写程序帮他解决类似的谜題。 这样的谜題具体可以描述为:有 nn个玩具小人围成一圈, 已知它们的职业和朝向。现在第11个玩具小人告诉小南一个包含mm条指令的谜題, 其中第 zz条指令形如“左数/右数第ss,个玩具小人”。 你需要输出依次数完这些指令后,到达的玩具小人的职业。

题解:
作为算法小白,看到这道题的时候,感觉和大一刷的noj后十题有一题比较像,感觉不需要复杂的算法,然后就开始了自己的尝试。题目规定按逆时针输入玩具人的信息,那么就将逆时针作为正方向,每个玩具人依次按数组下标0,1,2,···n排列。初始位置玩具人的下标为0,以k记录当前玩具人的下标,每执行一次命令就更新一次k。每条命令的长度记为length。当玩具人朝向为内且命令要求左数或玩具人朝向为外且右数时,相当于朝负方向数length个玩具人,因为玩具人下标范围为0~n-1,所以可以用(k -length+n)%n表示执行完该指令后指向的玩具人的下标;当玩具人朝向为内且命令要求右数或玩具人朝向为外且左数时,相当于朝正方向数length个玩具人,因为玩具人下标范围为0~n-1,所以可以用(k +length+n)%n表示执行完该指令后指向的玩具人的下标;遍历完所有命令后的k即代表题目所求玩具人的下标。
代码:
#include
using namespace std;
struct ToolPerson{
int direction;
string work;
};
int main()
{
int n,m,k = 0,orderdir,orderlength;//k表示执行完之前指令后当前指向的玩具人的位置;
ToolPerson tool[100000];
cin >> n >> m;
for(int i = 0;i < n;i ++)
{
cin >> tool[i].direction >> tool[i].work;
}
for(int j = 0;j < m;j ++)
{
cin >> orderdir >> orderlength;
if(tool[k].direction == orderdir)
{
k = (k - orderlength + n)%n;
}
else k = (k + orderlength + n)%n;
}
cout <<tool[k].work<<endl;
return 0;
}

猜你喜欢

转载自blog.csdn.net/winterfall115/article/details/82820930