nyoj ACM 幸運三角形

2021-07-29 18:41:20 字數 2017 閱讀 2902

描述

話說有這麼乙個圖形,只有兩種符號組成(『+』或者『-』),圖形的最上層有n個符號,往下個數依次減一,形成倒置的金字塔形狀,除第一層外(第一層為所有可能情況),每層形狀都由上層決定,相鄰的符號相同,則下層的符號為『+』,反之,為『-』;如下圖所示(n = 3 時的兩種情況):

如果圖中的兩種符號個數相同,那這個三角形就是幸運三角形,如上圖中的圖(2).

輸入 有多組測試資料(少於20組)。

每行含乙個整數n(0

<

n<20)

。 輸出 輸出相應的幸運三角形個數。

樣例輸入

3 4

樣例輸出 4 6

dfs和 bfs 要想提高速度,降低複雜度,就必須盡可能的剪枝。

這個題我一開始用深度優先搜尋dfs一邊搜尋,一遍判斷是否矛盾。但是在n>=15,雖然答案是對的,但是嚴重超時。後來看了一下討論區,被某位大牛給震驚了,竟然用操作二進位制的方法解出來了。

我的**dfs:

#include

#include

#include

using

namespace

std;

int n=0;

int a=0,b=0;

bool nomaodun(stack

s)break;

}if(i==1)

return

true;

int j=0;

int k=size;

j=size;

size=i;

for(i;i>=1;i--)

j=n-i+1+1;

}j=k;

for(i=size;i>=2;i--)

j=n-i+1+1;

}return

true;

}int main()

mystack.push(1);

a++;

while(!mystack.empty())

else

if(mystack.top()==0)

}if(a>(1+n)*n/4 || b>(1+n)*n/4)

qqq=true;

else

qqq=!nomaodun(mystack);

//qqq=!nomaodun(mystack);

while((qqq || flag==0) && !mystack.empty())

if(k==1)

if(a>(1+n)*n/4 || b>(1+n)*n/4)

qqq=true;

else

qqq=!nomaodun(mystack);}}

printf("%d\n",num);

}return

0;}

大牛的思想:

我們可以用乙個bit表示乙個』+』或者』-『,0表示『+』,1表示『-』。這樣表示用乙個整數表示一行。

比如,n=4,那麼第一行的數s的列舉就是從數0到15,然後要根據第一行的數計算第二行的數,其實,第二行的數就是s^(s>>1),每一位和相鄰位的異或,範圍從0到7,再繼續計算,直到最後一行的數為0或者1.也就是說,對n=4.建立乙個s[4]的陣列可以記錄下每一行的數,而每一行得數也容易從上一行得到。接下來,問題就變成了計算每行代表的那個整數所代表的二進位制數中1的個數。

按照大牛思想編寫的**:

#include

#include

#include

using

namespace

std;

int main()

int q=pow(2,n);

for(a[0]=0;a[0]0]++)

for(i=1;i<=n-1;i++)

if(k>(n+1)*n/4)

break;

}if(i>=n && k==(n+1)*n/4)

}printf("%d\n",num);

}return

0;}

幸運三角形

時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 話說有這麼乙個圖形,只有兩種符號組成 或者 圖形的最上層有n個符號,往下個數依次減一,形成倒置的金字塔形狀,除第一層外 第一層為所有可能情況 每層形狀都由上層決定,相鄰的符號相同,則下層的符號為 反之,為 如下圖所示 n 3 時...

幸運三角形

時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述話說有這麼乙個圖形,只有兩種符號組成 或者 圖形的最上層有n個符號,往下個數依次減一,形成倒置的金字塔形狀,除第一層外 第一層為所有可能情況 每層形狀都由上層決定,相鄰的符號相同,則下層的符號為 反之,為 如下圖所示 n 3 時的...

幸運三角形

時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 話說有這麼乙個圖形,只有兩種符號組成 或者 圖形的最上層有n個符號,往下個數依次減一,形成倒置的金字塔形狀,除第一層外 第一層為所有可能情況 每層形狀都由上層決定,相鄰的符號相同,則下層的符號為 反之,為 如下圖所示 n 3 時...