题目内容
众所周知,瑞神已经达到了CS本科生的天花板,但殊不知天外有天,人外有苟。在浩瀚的宇宙中,存在着一种叫做苟狗的生物,这种生物天生就能达到人类研究生的知识水平,并且天生擅长CSP,甚至有全国第一的水平!但最可怕的是,它可以发出宇宙射线!宇宙射线可以摧毁人的智商,进行降智打击!
宇宙射线会在无限的二维平面上传播(可以看做一个二维网格图),初始方向默认向上。宇宙射线会在发射出一段距离后分裂,向该方向的左右45°方向分裂出两条宇宙射线,同时威力不变!宇宙射线会分裂n 次,每次分裂后会在分裂方向前进 ai个单位长度。
现在瑞神要带着他的小弟们挑战苟狗,但是瑞神不想让自己的智商降到普通本科生那么菜的水平,所以瑞神来请求你帮他计算出共有多少个位置会被"降智打击"。
输入格式
输入第一行包含一个正整数n(n<=30) ,表示宇宙射线会分裂n次。
第二行包含n个正整数a1,a2…an,第 i个数ai 表示第 i次分裂的宇宙射线会在它原方向上继续走多少个单位长度。
输出格式
输出一个数 ans,表示有多少个位置会被降智打击。
输入示例
4
4 2 2 3
输出示例
39
解题思路
一看题目,啊,这左右两开花的样子,像极了bfs的笑容。
所以这道题用bfs显然是做的出来的
我们可以设置一个地图二维数组,来记录某个点是否有宇宙射线到达过。
剩余的就是bfs了,每次出队列之后处理当前方向的宇宙射线会到达的位置和到达终点时分裂出来的两个小的的方向就行。
那么我们可以用一个结构体来存储每个射线。
比赛当时的分数是40分,其他的爆内存了:
#include
#include
#include
using namespace std;
int map[350][350];
const int dirction[8]={
0,1,2,3,4,5,6,7};
const int dx[8]={
0,1,1,1,0,-1,-1,-1};
const int dy[8]={
1,1,0,-1,-1,-1,0,1};
struct point
{
int x,y;//坐标
int dir;//0 1 2 3 4 5 6 7
int a;//位移长度
int l;//层级
point(int _x,int _y,int _d, int _a,int _l)
{
x=_x;
y=_y;
dir=_d;
a=_a;
l=_l;
}
};
int a[30];
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
memset(map,0,sizeof(map));
queue<point>q;
point first(250,250,0,a[0],0);
q.push(first);
while(!q.empty())
{
point now=q.front();
q.pop();
int tx=now.x,ty=now.y;
//map[tx][ty]=1;
for(int j=0;j<now.a;j++)
{
tx+=dx[now.dir];
ty+=dy[now.dir];
map[tx][ty]=1;
}
int offset[2];
if(now.dir==0)
{
offset[0]=1;offset[1]=7;
}
else if(now.dir==7)
{
offset[0]=0,offset[1]=6;
}
else
{
offset[0]=now.dir+1;
offset[1]=now.dir-1;
}
if(now.l!=n-1)
for(int i=0;i<=1;i++)
{
q.push(point(tx,ty,offset[i],a[now.l+1],now.l+1));
}
}
int sum=0;
for(int i=0;i<500;i++)
for(int j=0;j<500;j++)
if(map[i][j]==1)
sum++;
cout<<sum<<endl;
}
在比赛结束之后发现,这玩意看那个示例图可以发现,这个似乎是…轴对称的图形?
那么我们就可以只处理其中一边呀!最后除了轴上的点以外其他的点的值都×2就行了。
不过想到这个的时候oj已经关掉了,所以就不贴改过的代码了,修改起来也挺简单的。