问题描述:
宇宙射线会在无限的二维平面上传播(可以看做一个二维网格图),初始方向默认向上。宇宙射线会在发射出一段距离后分裂,向该方向的左右45°方向分裂出两条宇宙射线,同时威力不变。宇宙射线会分裂n次,每次分裂后会在分裂方向前进ai 个单位长度。计算出共有多少个位置会被打击。
输入:
输入第一行包含一个正整数n(n <= 30),表示宇宙射线会分裂n次,第二行包含n个正整数a1,a2…an,第i个数ai(ai <= 5)表示第i次分裂的宇宙射线会在它原方向上继续走多少个单位长度。
输出:
输出一个数ans,表示有多少个位置会被降智打击。
输入样例:
4
4 2 2 3
输出样例:
39
问题描述:
这道题思路很清晰,由于每条射线都不受其他射线的干扰,所以最简单的思路就是递归思想,经分析可知,射线最多有8个方向,每到一个分裂点只会往当前方向的相邻两个方向辐射,故利用递归很容易能求得答案的解,但是时间性能太差了,所以要改善时间性能,分析可知,射线往每个方向不会超过150个距离,所以可以直接用二维数组对点进行标记,当c[i][j]为1时,表示该点已到达,同时要用斯维数组对射线进行标记,避免很多重复搜索。这样,时间性能就改善了不少,题目得解。
实验代码:
#include<iostream>
using namespace std;
int dx[8]={0,1,1,1,0,-1,-1,-1};
int dy[8]={1,1,0,-1,-1,-1,0,1};
int a[31]={0};
bool b[300][300][8][33] = {0};
bool c[333][333];
int n;
int ans;
void shexian(int d,int fx,int x,int y)
{
if(d>=n)
return ;
int xx=x,yy=y;
for(int i=1;i<=a[d];i++)
{
xx=x+i*dx[fx];
yy=y+i*dy[fx];
if(!c[xx][yy])
{
c[xx][yy]=1;
ans++;
}
}
b[x][y][fx][d]=1;
int f=(fx+1)%8;
if(!b[xx][yy][f][d+1])
shexian(d+1,f,xx,yy);
f=(fx+7)%8;
if(!b[xx][yy][f][d+1])
shexian(d+1,f,xx,yy);
}
int main(void)
{
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
shexian(0,0,150,150);
cout<<ans<<endl;
return 0;
}