CSP-M1 C - 可怕的宇宙射线
时间与内存限制 每个测试点 1000ms 262144KB
题目描述 众所周知,瑞神已经达到了CS本科生的天花板,但殊不知天外有天,人外有苟。在浩瀚的宇宙中,存在着一种叫做苟狗的生物,这种生物天 生就能达到人类研究生的知识水平,并且天生擅长CSP,甚至有全国第一的水平!但最可怕的是,它可以发出宇宙射线!宇宙射线可以摧毁 人的智商,进行降智打击! 宇宙射线会在无限的二维平面上传播(可以看做一个二维网格图),初始方向默认向上。宇宙射线会在发射出一段距离后分裂,向该方向的 左右45°方向分裂出两条宇宙射线,同时威力不变!宇宙射线会分裂 次,每次分裂后会在分裂方向前进 个单位长度。 现在瑞神要带着他的小弟们挑战苟狗,但是瑞神不想让自己的智商降到普通本科生 那么菜的水平,所以瑞神来请求你帮他计算出共有多 少个位置会被"降智打击"
输入描述
输入第一行包含一个正整数 ,表示宇宙射线会分裂 次 第二行包含n个正整数 ,第 个数 表示第 次分裂的宇宙射线会在它原方向上继续走多少个单位长度。
输出描述
输出一个数 ,表示有多少个位置会被降智打击
样例输入
4
4 4 2 2 3
样例输出
39
数据点说明
数据点 | n |
---|---|
10% | <=10 |
40% | <=20 |
100% | <=30 |
解题思路
利用递归DFS
DFS都为探索到做深
为了不TL 我们要用到剪枝
将操作记录下来 再次遇到时就直接返回
Code
#include<iostream>
using namespace std;
int ba=200,bb=200;
bool kk[400][400]={0};
bool z[400][400][2][2][100];
int n;
int a[40];
int ans;
void w(int bba,int bbb,int nt,int tx,int ty){
//(bba,bbb)为上一个点的x y位置,nt为执行层数,(tx,ty)为上一个执行方向
if(nt>n)return;
if(z[bba][bbb][tx][ty][nt]){return;}//剪枝
z[bba][bbb][tx][ty][nt]=1;
int nba=bba;int nbb=bbb;
int x1,x2,y1,y2;
if(tx==1&&ty==0){//用(tx,ty)求出下俩个方向
x1=1;y1=1;x2=1;y2=-1;
}else if(tx==0&&ty==1){x1=-1;y1=1;x2=1;y2=1;
}else if(tx==1&&ty==1){x1=0;y1=1;x2=1;y2=0;
}else if(tx==-1&&ty==-1){x1=0;y1=-1;x2=-1;y2=0;
}else if(tx==-1&&ty==0){x1=-1;y1=-1;x2=-1;y2=1;
}else if(tx==0&&ty==-1){x1=1;y1=-1;x2=-1;y2=-1;
}else if(tx==-1&&ty==1){x1=-1;y1=0;x2=0;y2=1;
}else if(tx==1&&ty==-1){x1=1;y1=0;x2=0;y2=-1;
}
for(int y=0;y<a[nt];y++){//走左边
nba+=x1;nbb+=y1;
if(kk[nba][nbb]!=1){ans++;
}
kk[nba][nbb]=1;
}
if(nt<n){w(nba,nbb,nt+1,x1,y1); //如果未结束则进入下一个循环
}else{return;
}
nba=bba;nbb=bbb;
for(int y=0;y<a[nt];y++){
nba+=x2;nbb+=y2;
if(kk[nba][nbb]!=1){ans++;
}
kk[nba][nbb]=1;
}
if(nt>=n)return;
w(nba,nbb,nt+1,x2,y2);进入下个循环
return;
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
for(int i=0;i<a[0];i++){//最初的操作 向前走
ans++;
kk[ba][bb]=1;
bb++;
}
w(ba,bb,1,0,1);
printf("%d\n",ans);
return 0;
}