P
a
r
t
Part
Part
1
1
1 读题
题目描述:
在一个无限大的二维坐标系中,有一个机器人在原点(面朝什么方向都随意hhh)。
同时他拥有一个长度为
n
n
n的命令序列。
其中第
i
i
i个命令会让它向当前方向移动
a
i
a_i
ai个位置,然后顺时针旋转
a
i
∗
90
a_i*90
ai∗90度。
同时,它会重复执行这个命令序列
T
T
T次,求它最后停下来的位置和原点的曼哈顿距离(求得是曼哈顿距离所以一开始面朝什么方向都随意)。
输入格式:
第一行包括两个正整数
n
,
T
n,T
n,T。
第二行包括
n
n
n个用空格隔开的正整数
a
i
a_i
ai。
输出格式:
一行一个非负整数,求机器人最后停下来的位置和原点的曼哈顿距离。
输入样例1:
5 3
1 2 3 4 5
输出样例1:
9
输入样例2:
10 100
97 46 39 12 54 89 32 76 88 100
输出样例2:
0
数据范围与提示:
对于
60
%
的数据:
1
≤
n
,
T
,
a
i
≤
500
对于 60\%的数据 :1≤n,T,a_i≤500
对于60%的数据:1≤n,T,ai≤500;
对于
100
%
的数据:
1
≤
n
,
T
,
a
i
≤
5
×
1
0
5
对于 100\%的数据 : 1≤n,T,a_i≤5\times10^5
对于100%的数据:1≤n,T,ai≤5×105;
P a r t Part Part 2 2 2 思路
我们用数组
a
a
a存储命令序列,然后根据
n
n
n的大小进行输入。
设置方向数组
d
x
dx
dx和
d
y
dy
dy,根据题意,我们知道是顺时针旋转,所以我们设置
d
x
d x
dx=
−
1
(
上
)
,
0
(
左
)
,
1
(
下
)
,
0
(
右
)
{ −1( 上 ) , 0 ( 左 ) , 1 ( 下 ) , 0 ( 右 )}
−1(上),0(左),1(下),0(右),同理,设置
d
y
dy
dy =
0
,
−
1
,
0
,
1
{ 0 , − 1 , 0 , 1 }
0,−1,0,1。
接下来我们设置变量
c
i
r
cir
cir代表角度,使用方向数组时下标为
c
i
r
÷
90
cir÷90
cir÷90,我们可以写成:
c
i
r
=
(
c
i
r
+
a
[
i
]
×
90
)
%
360
cir=(cir+a[i]×90)\%360
cir=(cir+a[i]×90)%360。
前进时我们也需要使用方向数组,所以定义变量
x
x
x和
y
y
y代表当前机器人所处位置的横坐标与纵坐标,我们可以写成:
x
+
=
a
[
i
]
×
d
x
[
c
i
r
÷
90
]
x+=a[i]\times dx[cir \div 90]
x+=a[i]×dx[cir÷90]
y
+
=
a
[
i
]
×
d
y
[
c
i
r
÷
90
]
y+=a[i]\times dy[cir \div 90]
y+=a[i]×dy[cir÷90]
P a r t Part Part 3 3 3 代码
#include<bits/stdc++.h>
using namespace std;
int dx[4]={-1,0,1,0},dy[4]={0,-1,0,1},a[500005],x,y,cir,n,t;
int main(){
cin>>n>>t;
for(int i=1;i<=n;i++)cin>>a[i]//命令序列
for(int i=1;i<=t;i++)//执行t次
for(int j=1;j<=n;j++){
x+=a[j]*dx[cir/90],y+=a[j]*dy[cir/90];//前进,此处解释自行上划
cir=(cir+a[j]*90)%360;//转弯,此处解释自行上划
}
cout<<abs(x)+abs(y);//曼哈顿距离,可能有负数,所以要用绝对值
}
P a r t Part Part 4 4 4 结果
最终只得了60分,还超时了
原因如下:
对于
100
%
的数据:
1
≤
n
,
T
,
a
i
≤
5
×
1
0
5
对于 100\%的数据 : 1≤n,T,a_i≤5\times10^5
对于100%的数据:1≤n,T,ai≤5×105
而暴力枚举自然会超时
P a r t Part Part 5 5 5 改进
我们先只做
1
1
1次命令序列,看看 x、y和cir各有那些变化,用变量nx 、 ny和nc来存储当前 x、 y和cir的值,循环 T−1次,判断当前cir的值,我们分以下几种情况进行讨论:
c
i
r
=
0
,
x
+
=
n
x
,
y
+
=
n
y
,
c
i
r
=
(
c
i
r
+
n
c
)
%
360
cir=0,x+=nx,y+=ny,cir=(cir+nc)\%360
cir=0,x+=nx,y+=ny,cir=(cir+nc)%360
c
i
r
=
90
,
x
−
=
n
y
,
y
+
=
n
x
,
c
i
r
=
(
c
i
r
+
n
c
)
%
360
cir=90, x-=ny,y+=nx,cir=(cir+nc)\%360
cir=90,x−=ny,y+=nx,cir=(cir+nc)%360
c
i
r
=
180
,
x
∗
=
n
x
,
y
∗
=
n
y
,
c
i
r
=
(
c
i
r
+
n
c
)
%
360
cir=180, x*=nx,y*=ny,cir=(cir+nc)\%360
cir=180,x∗=nx,y∗=ny,cir=(cir+nc)%360
c
i
r
=
270
,
x
+
=
n
y
,
y
−
=
n
x
,
c
i
r
=
(
c
i
r
+
n
c
)
%
360
cir=270,x+=ny,y-=nx,cir=(cir+nc)\%360
cir=270,x+=ny,y−=nx,cir=(cir+nc)%360
P a r t Part Part 6 6 6 代码(AC版)
#include<bits/stdc++.h>
using namespace std;
int dx[4]={-1,0,1,0},dy[4]={0,-1,0,1},a[500005],cir,n,t;
long long x,y;
int main(){
cin>>n>>t;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++){
x+=a[i]*dx[cir/90],y+=a[i]*dy[cir/90];
cir=(cir+a[i]*90)%360;
}
long long nx=x,ny=y,nc=cir;//储存当前x,y,cir的值
for(int i=2;i<=t;i++){
switch(cir){
case 0:x+=nx,y+=ny;break;
case 90:x-=ny,y+=nx;break;
case 180:x-=nx,y-=ny;break;
case 270:x+=ny,y-=nx;break;
}
cir=(cir+nc)%360;
}
cout<<abs(x)+abs(y);
}
P
a
r
t
Part
Part
7
7
7 总结
本题的难点就是对于超时这一点。
看完题解后,会不会感到很简单呢?赶快去试试吧!