描述
話說有這麼乙個圖形,只有兩種符號組成(『+』或者『-』),圖形的最上層有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 時...