宇宙線は、(図は2次元格子とみなすことができる)、初期デフォルト上方向が、宇宙線が分割方向の方向に向かって45°程度の距離で除算した後に放出されるワイヤレス二次元平面上を伝播します2本の宇宙線、同一の電源ています。宇宙線は、各時分割単位の長さは、分割の方向に進めるAI、n回に分割します。ヒットさせる位置の総数を計算してください。
正の整数の最初のラインの入力N(N <= 30)、N宇宙線は、ビューを分割します表します。2行目は含まnは整数A1、A2、...、i番目の桁は、Al(<= 5 AI)宇宙線の数のi番目の分割は、元の方向に単位長さを取るし続ける表します。
数のANSの出力は、多くのポジションがストライキにあったかを示しています。
サンプル入力:
4
4 2 2 3
サンプル出力:
39
アイコン:
アイデア:
- すべてのポイントのために、わずか8順方向があるかもしれません。そして時間が45度時計回り及び反時計回りであってもよく、それは各記録の方向にのみ変化するように、それは8%であることができ、書き込みのx、y座標の変化に応じて、時計回りまたは反時計方向のいずれかに対応することができます+1と-1の方法は、ステアリングを取得します。
- ブール値答えを得るために、座標(x、y)がアクセスされるかどうかを最後に計算されたヒットポイントの数を示すために二次元配列ヒット[X] [Y]を利用してもよいです
- 各ブランチノードのための2つの再帰検索を実行し続けるためにいくつかの方法全体の検索を使用します
- 真上の考えに基づいて、我々は、以上の5つのポイントは、ポイントの残りの部分はTLE、時間の複雑さを軽減するために、我々は今、プルーンプログラムにする必要がありますすることができた場合
- あまりにも多くの時間を消費する主な理由は、同じポイントに到達するための複数のブランチ、同じ点について、異なる分岐が存在する間の時間の点の数が多い、特定のレベルの間に発生し得る場合には、彼はそれが多くの冗長性につながった、行くことは最後になります。同じ点は直接のうち、発生した場合ので、層内の特定の時点で特定の方向を示すために使用される4つの次元配列を作成します。
#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int dirx[8]={0,-1,-1,-1,0,1,1,1};
int diry[8]={1,1,0,-1,-1,-1,0,1};//一圈方便循环
int ans=0;
int t[31];
int n;
bool hit[400][400]={false};
bool visit[31][400][400][8];
void digui(int now,int x,int y,int d)
{
if(visit[now][x][y][d]==true)//降低复杂度
return;
visit[now][x][y][d]=true;
if(!hit[x][y])
{
hit[x][y]=true;
ans++;
}
int temp_x=x,temp_y=y;
for(int i=0;i<t[now]-1;i++)
{
temp_x+=dirx[d];
temp_y+=diry[d];
if(!hit[temp_x][temp_y])
{
hit[temp_x][temp_y]=true;
ans++;
}
}
if(now==n) return;//返回条件
int temp_d=(d+1)%8;//45
digui(now+1,temp_x+dirx[temp_d],temp_y+diry[temp_d],temp_d);
temp_d=(d+7)%8;
digui(now+1,temp_x+dirx[temp_d],temp_y+diry[temp_d],temp_d);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>t[i];
digui(1,200,200,0);//第一个的方向肯定是向上
cout<<ans;
return 0;
}