可怕的宇宙射線 dfs 剪枝

2021-10-03 22:06:41 字數 3016 閱讀 1063

寫在前面:對於這個問題,首先我們可以採用暴力bfs或者dfs,但是這種演算法的複雜度是指數級的,如果考慮**30次,那麼它的迴圈次數是2

302^

230,如果在正規比賽中肯定會超時,在詢問了大佬之後,這個問題可以採用dfs加上剪枝來解決,這裡和大家分享一下

在浩瀚的宇宙中,存在著1種生物, 這種生物可以發出宇宙射線!宇宙射線可以摧毀人的智商,進行降智打擊!

宇宙射線會在無限的二維平面上傳播(可以看做乙個二維網格圖),初始方向預設向上。宇宙射線會在發射出一段距離後**,向該方向的左右45∘

45^45

∘方向**出兩條宇宙射線,同時威力不變!宇宙射線會**n

nn次,每次**後會在**方向前進a

aa個單位長度。

你的任務是計算出會有多少個位置被降智打擊。

input:輸入第一行包含乙個正整數n(n

≤30)n(n\leq 30)

n(n≤30

),表示宇宙射線會**nnn次

第二行包含n個整數a1,

a2..

.ana_,a_...a_

a1​,a2

​...

an​,第i

ii個數ai(

ai≤5

)a_(a_\leq 5)

ai​(ai

​≤5)

表示第i

ii次**的宇宙射線會在它原方向上繼續走過多少個單位長度

output:

輸出乙個數ans

ansan

s,表示有多少個位置會被降智打擊

樣例輸入:

442

23

樣例輸出:

39
樣例解釋:

宇宙射線的**過程

首先我們通過觀察,宇宙射線的**其實是對稱的,我們只要求一半,另一半的座標就可以通過對稱得到。所以,在每一次**時,我們只考慮乙個方向,另乙個方向可以通過對稱得到。但是,不同的邊的對稱次數是不同的,例如,第一條邊,也就是圖中的出發邊,它不需要對稱,最後一條邊,也是圖中紫色的邊,它需要對稱3次。由此,我們可以得到,如果宇宙射線**n次,那麼最後一條邊需要對稱n-1次,倒數第二條邊需要對稱n-2次,由此類推,所以,我們就想到用dfs,首先遍歷到最後一條邊,然後從最後一條邊開始遍歷並回溯,回溯每一層最後一條邊都會對稱一次,其餘邊同理,這樣就能滿足我們的對稱需求。

在每一次**時,都會有兩個方向**,這裡我們只考慮乙個方向,朝右45∘

45^45

∘方向**,所以這裡我指定了兩個偏移量陣列,第0個方向是豎直向上**,然後按逆時針方向每變換45∘

45^45

∘度為乙個方向,那麼每一次**的方向計算為,假設原方向為dir

dirdi

r:(dir

+7)m

od8(dir+7)mod8

(dir+7

)mod

8,這樣我們就得到了每一次**的方向。每個射線都是沿**方向發散n個長度。

在考慮完方向問題,還有乙個對稱問題,對稱線一共有四條,如下圖:

幾幅圖旨在說明對稱關係,和實際的**圖的情況有些不類似,並且對稱點的計算方法高中都學過,這裡直接給出了對稱點的座標。

有了這幾個對稱關係,我們就能很容易的找到已經遍歷的對稱點。

對於演算法實現,上述都已經描述的差不多了。這裡我使用了stl中的set,因為他有乙個好處是自動去重,這樣我們就不用考慮乙個點是否已經到達過,直接將所有的點插入set中,set自動去除重複的點。這樣最後set中元素的個數就是我們的結果。

對於這個題目,我們最直接想到的就是暴力bfs和dfs,如果在沒有時間約束的條件下這樣也是可行的,如果一旦加上了時間約束,這往往就不盡人意了,所以我們要在此基礎上加上合理的剪枝,進一步減少冗餘的工作,減少時間。

#include

#include

#include

#include

#include

using

namespace std;

struct point};

set path;

//全域性變數,儲存已經到的點

int a[31]

;//八個方向,第0個方向為預設的向上方向

int x_move=

;int y_move=

;//startx和starty是**時的點

void

search

(int pnum,

int dir,

int startx,

int starty,

int n)

else

if(dir==

1||dir==5)

else

if(dir==

2||dir==6)

else

if(dir==

3||dir==7)

}//將已經到的邊對稱完,然後遍歷以startx和starty為終點的邊

for(

int i=

0;iintmain()

可怕的宇宙射線

題意 宇宙射線會在無限的二維平面上傳播 可以看做乙個二維網格圖 初始方向預設向上。宇宙射線會在發射出一段距離後 向該方向的左右45 方向 出兩條宇宙射線,同時威力不變。宇宙射線會 n次,每次 後會在 方向前進ai 個單位長度。計算出共有多少個位置會被打擊。輸入 輸入第一行包含乙個正整數n n 30 ...

CSP M1 C 可怕的宇宙射線 dfs剪枝

宇宙射線在二維平面內傳播,一段距離後向左右45 威力不變。宇宙射線會 n次,每次 後前進ai個單位再 計算共有多少二維平面內的點受到宇宙射線的攻擊。第一行 次數 n n 30 第二行 n個數,第i個數ai表示第i次 後前進的距離,ai 5 乙個數ans,表示共有ans個點被攻擊 每乙個點的狀態有橫座...

C 可怕的宇宙射線

宇宙射線會在無限的二維平面上傳播 可以看做乙個二維網格圖 初始方向預設向上。宇宙射線會在發射出一段距離後 向該方向的左右45 方向 出兩條宇宙射線,同時威力不變!宇宙射線會 n 次,每次 後會在 方向前進 ai個單位長度。求有多少個位置會被打擊。輸入第一行包含乙個正整數n n 30 表示宇宙射線會 ...