求n個資料的組合:
由數學知識,可以知道一共有2n個子集
用二進位制進行對照會非常直觀
子集空集
a1a0
a1 , a0
a2a2, a0
a2, a1
a0,a1, a2
二進位制數
0 0 0
0 1 0
0 0 1
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
給出n個資料,問從這n個資料中取出3個組成三角形,有多少種取法?
經典的組合問題
下面上**
while
(kk)
//統計1的個數
例如:1011
&(1011-1
)=1010
1010&(
1010-1
)=1010
&1001
=1000..
..
完整**
#include
//萬能標頭檔案
using
namespace std;
int sd[
100001];
// 定義乙個儲存邊的陣列
int jmt[3]
;//儲存陣列
bool
judge
(int
* a)
//判斷函式
intmain()
//輸入資料
for(
int i =
0; i<(1
<; i++
)//統計1的個數
if(counted==3)
}}if(
judge
(jmt)
)num++
;memset
(jmt,0,
sizeof
(jmt));
//清零
} cout
}
由於此種解法的時間複雜度為2n,因此對於此題應該換一種解法
這裡考慮用dfs的方法(本質為三層for迴圈)
以下是**
#include
using
namespace std;
int state , n , counted;
int book[
2501];
int arr[
2501
], jmt[3]
;bool
judge
(int
* a)
void
dfs(
int state)
else
if(state<3)
for(
int i =
0; i < n ; i++)}
return;}
intmain()
dfs(0)
; cout<6
}
此種解法如果時間限制為1s的話,仍然無法達到要求,因此應該考慮更加高階的演算法,下面的演算法是sort快排+二分搜尋。
下面上**
#include
//萬能標頭檔案
using
namespace std;
int sd[
2501];
int jmt[3]
;int book[
2501];
//判重陣列
int counted;
bool
judge
(int
* a)
//判斷函式
intsrh
(int
* arr ,
int num ,
int start ,
int end)
//二分搜尋函式
return-1
;//沒搜尋到,返回-1
}int
main()
sort
(sd,sd+n)
;//進行快排,使序列由小到大進行排列,使得可以使用二分法
for(
int i =
0; i < n ; i++)}
}else
//沒搜尋到的話,進行遍歷
for(
int k =
0; k < n ; k++)}
}memset
(book,0,
sizeof
(book));
//清零進行下一步迴圈迭代
} cout<2/重複計算了兩次,故除以二
return0;
}
利用位運算解決排序問題(摘自程式設計珠璣)
問題背景 已知資料的取值範圍在0 10000000,且所取資料不重複,將輸入的資料排序並盡可能的使用少的記憶體空間 define bitsperrword 32 define shift 5 define mask 0x1f define n 10000000 include int a 1 n b...
位運算解決N 皇后問題
描述 位運算是定義在整數上的運算。但在做位運算的時候,並不把整數看作整數,而是將它們看做一系列二進位制數字,逐位進行運算。位運算有6種,他們的名稱,運算子及運算規則如下 與 and 5 6 4 101 110 100 或 or 5 6 7 101 110 111 異或 xor 5 6 3 101 1...
C 利用棧解決運算問題
2017 06 27 19 19 18 第一步需要將中綴表示式轉為字尾表示式。這步的轉化可以說是本題的核心。主要的轉化手段是利用棧,有如下幾個規則 int toint stringin int priority chara bool isdig char a 保證每次入棧的符號的優先順序都比當前的棧...