|
30鱼币
A. 计算鸭玩耍
描述
计算鸭正在一块无穷打的网格地面上玩耍,他站在A位置
计算鸭准备了n个指令a[i]
对于每个指令,计算鸭都会执行如下操作
1:往当前方向移动a[i]的距离
2:往右转90度,重复a[i]次
计算鸭决定执行这n个指令T次,假设执行完后停留在了B位置,请问A与B的曼哈顿距离是多少
曼哈顿距离指的是两个点的x坐标的绝对值之差与y坐标的绝对值之差的和
输入
3 1
1 2 3
输出
2
本帖最后由 Neverturnback 于 2019-7-28 03:54 编辑
/***************
程序思路:
一,单个旋转角度是90度,所以总共只有4个方向,两组相反的方向移动的距离和的差值之和就是曼哈顿距离
二,把执行n条指令看成一个整体,每一次执行完n条指令的曼哈顿距离都相等只是方向不同,有3种情况:
1.方向不变,那么把这n条指令执行T次,所得到的曼哈顿就是用T乘以单个n的曼哈顿距离
2.方向为原来的相反方向,那么T为单数,曼哈顿距离为单个n的曼哈顿距离,T为偶数,曼哈顿距离为0(和思路一的原理类似)
3.方向改变90度(无论顺时针改变还是逆时针改变都一样), 用T%4(和思路一的原理类似具体看后面代码)
***************/
#include <iostream>
using namespace std; //这边偷懒了,严格来说不能打开全部权限,只打开cin,cout,endl的权限
#define CMDMAX 100 //最大指令个数
struct MdMessage{
int nMD;
char changeAngle;
};
void GetNMD(int* nCmd, MdMessage* nMD, int cmdNum) //执行完n条指令后的曼哈顿距离和与初始方向相比改变的方向角度
{
int sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0;//sum0记录与初始方向偏差0度的方向移动的总距离, sum1记录与初始方向偏差90度的方向移动的总距离
//sum2记录与初始方向偏差180度的方向移动的总距离, sum3记录与初始方向偏差270度的方向移动的总距离
int offsetDirection = 0;//当前起始方向与初始方向的偏差
int xMD = 0, yMD = 0;
for (int i = 0; i < cmdNum; ++i)
{
switch (nCmd[i] % 4 + offsetDirection)//以初始方向为参考点时,每一次旋转方向不一定和初始方向一致,所以用offsetDirection记录当前起始方向方向与初始方向的偏差
{
case 0:
{
offsetDirection = 0;
sum0 += nCmd[i];
}break;
case 1:
{
offsetDirection = 1;
sum1 += nCmd[i];
}break;
case 2:
{
offsetDirection = 2;
sum2 += nCmd[i];
}break;
case 3:
{
offsetDirection = 3;
sum3 += nCmd[i];
}break;
}
}
xMD = sum0 > sum2 ? sum0 - sum2 : sum2 - sum0; //x的绝对值之差(这里假设了初始方向为北,初始方向为哪个方向都一样,只要把xMD, 和yMD的值交换就行了)
yMD = sum1 > sum3 ? sum1 - sum3 : sum3 - sum1; //y的绝对值之差
nMD->nMD = xMD + yMD; //执行n条指令后的曼哈顿距离
nMD->changeAngle = offsetDirection; //执行完n条指令后与初始方向的偏差
}
int GetTn_MD(int T, MdMessage const & nMD) //将n条指令执行T次后的曼哈顿距离
{
switch (nMD.changeAngle)
{
case 0: //执行n条指令后方向不变
return nMD.nMD * T; //这里用了return 所以每个case后面没跟break
case 1:
case 3: //执行n条指令后方向改变90度
{
switch (T % 4)
{
case 0:
return 0;
case 1:
case 3:
return nMD.nMD;
case 2:
return nMD.nMD * 2;
}
}
case 2: //执行n条指令后方向改变180度
return nMD.nMD * (T % 2);
}
}
int main()
{
int nCmd[CMDMAX], cmdNum = 0, T = 0;
MdMessage nMD;
cout << "请输入指令的个数(必须为不大于100的非负整数,回车结束输入):";
cin >> cmdNum; //这里偷个懒,要判断输入的是不大于100的非负整数才行
cout << "请输入n个指令的次数(必须为非负整数,回车结束输入):";
cin >> T; //偷懒同上
cout << "请输入指令(必须为非负整数,每个指令之间用空格隔开,当行不够时换行,最后一个指令结束后回车结束输入):";
for (int i = 0; i < cmdNum; ++i)
cin >> nCmd[i]; //这里我也偷懒了,要判断输入的是非负整数
GetNMD(nCmd, &nMD, cmdNum);
cout << "将n条指令执行T次后曼哈顿距离为:"<<GetTn_MD(T, nMD)<<endl;
getchar();//读取缓冲区的回车符
getchar();//暂停程序好观察结果
return 0;
}
|
最佳答案
查看完整内容
/***************
程序思路:
一,单个旋转角度是90度,所以总共只有4个方向,两组相反的方向移动的距离和的差值之和就是曼哈顿距离
二,把执行n条指令看成一个整体,每一次执行完n条指令的曼哈顿距离都相等只是方向不同,有3种情况:
1.方向不变,那么把这n条指令执行T次,所得到的曼哈顿就是用T乘以单个n的曼哈顿距离
2.方向为原来的相反方向,那么T为单数,曼哈顿距离为单个n的曼哈顿距离,T为偶数,曼哈顿距离为0(和思路一的原理 ...
|