2013-03-05 187 views
-4

這個問題讓我瘋狂。頂部的代碼在我的電腦上執行大約0.3秒,而底部的代碼在大約2.7秒內執行。但是,我試圖將第二個代碼調整爲與第一個代碼類似,但它似乎總是比較慢。誰能告訴我爲什麼第一個代碼比第二個執行速度快得多?這段代碼爲什麼更快?

更快的代碼

#include <cstdio> 
#include <set> 
#define ls(x) (x & (-x)) 
using namespace std; 
int tc, n; 
set<long long> s; 
long long p, a[35]; 
int main() { 
    freopen("mini3b.in","r",stdin); 
    scanf("%d", &tc); 
    while (tc--) { 
     s.clear(); 
     scanf("%lld%d", &p, &n); 
     for (int i = 0; i < n; ++i) scanf("%lld", &a[i]); 
     int h = n/2; 
     for (int i = 0; i < (1<<h); ++i) { 
      long long sum = 0; 
      for (int j = 0; j < h; ++j) if (i&(1<<j)) sum += a[j]; 
      s.insert(sum); 
     } 
     bool found = false; 
     for (int i = 0; (i < (1<<(n-h))) && !found; ++i) { 
      long long sum = 0; 
      for (int j = 0; j < n-h; ++j) if (i&(1<<j)) sum += a[h+j]; 
      if (s.find(p-sum) != s.end()) found = true; 
     } 
     printf(found? "YES\n":"NO\n"); 
    } 
} 

慢的代碼

#include <cstdio> 
#include <set> 
using namespace std; 
long long n, bars[35]; 
int t, p; 
set<long long> s; 
int main(){ 
    freopen("mini3b.in","r", stdin); 
    scanf("%d", &t); 
    while (t--){ 
     s.clear(); 
     scanf("%lld%d", &n, &p); 
     for (int i=0;i<p;++i) scanf("%lld", &bars[i]); 
     int limit=p/2; 
     for (int i=0;i<(1<<limit);++i){ 
      long long sum=0; 
      for (int j=0;j<limit;++j) if (i&(1<<j)) sum+=bars[j]; 
      s.insert(sum); 
     } 
     bool found=false; 
     for (int i=0;i<(1<<(n-limit))&&!found;++i){ 
      long long sum=0; 
      for (int j=0;j<p-limit;++j) if (i&(1<<j)) sum+=bars[limit+j]; 
      if (s.find(n-sum) != s.end()) 
       found=true; 
     } 
     printf(found?"YES\n":"NO\n"); 
    } 
} 
+2

我希望你比較發佈版本。 – AnatolyS 2013-03-05 11:52:12

+0

第一個宏有一個預處理器宏,但我沒有看到它在任何地方使用... – aqua 2013-03-05 11:53:25

+0

如果我正確理解你的問題,兩個都在同一臺計算機上一個接一個地執行。 – cortex 2013-03-05 11:54:07

回答

3

在for循環中你有

for (int i = 0; (i < (1<<(n-h))) && !found; ++i) { // fast one 
         ^

第四
for (int i=0;i<(1<<(n-limit))&&!found;++i){ // slow one 
        ^

請注意,快速代碼中的'n'是慢速代碼中的'p'。所以你應該有

for (int i=0;i<(1<<(p-limit))&&!found;++i){ // slow one 
        ^
+0

使用較長變量名稱的另一個原因(而不是使用相同名稱的不同方式)。我剛剛找到了同樣的東西,但是我的速度稍慢... – 2013-03-05 12:14:18

+0

我永遠都不會發現:/謝謝 – cortex 2013-03-05 12:35:41