n<=30 t[i]<=5 算重复的有2^30个 但是每层最多只能使地图半径扩大5,所以直径最大为300 所有点都落在300*300矩形内
不重复的点只有9e4个,bfs暴力模拟烟花扩散过程即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e2+20;
struct node{
int x,y,cnt,dir;//cnt:烟花层数,dir:进入的方向
}tmp;
int t[N],n;
int mp[N][N];
int mark[N][N][35][6];
int asp[][2]={{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};
void bfs()
{
queue<node> q;
tmp.x=tmp.y=150;
tmp.cnt=1;tmp.dir=0;
q.push(tmp);
mark[150][150][1][0]=1;
while(!q.empty())
{
tmp=q.front();
q.pop();
int nx=tmp.x,ny=tmp.y,num=tmp.cnt,k=tmp.dir;
for(int i=1;i<=t[num];i++)//走t[i]后,分裂
{
nx+=asp[k][0];
ny+=asp[k][1];
mp[nx][ny]=1;//
//cout<<nx<<" "<<ny<<endl;
}
if(num!=n)
{
int kl=(k-1+8)%8,kr=(k+1)%8;
tmp.x=nx,tmp.y=ny,tmp.cnt=num+1;
//分裂点,方向不同的入队
if(!mark[nx][ny][num+1][kl])
{
mark[nx][ny][num+1][kl]=1;
tmp.dir=kl;
q.push(tmp);
}
if(!mark[nx][ny][num+1][kr])
{
mark[nx][ny][num+1][kr]=1;
tmp.dir=kr;
q.push(tmp);
}
}
}
}
int main()
{
while(cin>>n)
{
memset(mp,0,sizeof(mp));
memset(mark,0,sizeof(mark));
for(int i=1;i<=n;i++)
cin>>t[i];
bfs();
int ans=0;
for(int i=0;i<=300;i++)
{
for(int j=0;j<=300;j++)
{
if(mp[i][j])
ans++;
}
}
cout<<ans<<endl;
}
return 0;
}