刷題最佳代碼風格

因爲算法題通常都有6k最大文件限制,又要節約打字時間又要追求效率和準確率,和工程的要求有很大的不一樣。因此儘可能要使用簡潔的風格。ios

以前是和工程同樣嚴格遵循google C++編程規範,浪費了apm的調試還容易出錯,寫出的程序性能還不高比別人的難看代碼多上百ms。爲了提升準確率,我要一改之前的迂腐做風,不到200行的程序講究什麼編程規範。我仔細研究了曾經的top coder NO.1 Petr的第一視角,要找出一種最有效的代碼風格:算法

SRM 529編程

 codeforces NO.1 tourist的代碼:ide

#include <cstring>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <memory.h>
#include <cassert>

using namespace std;

const int N = 200010;

int n[3];
vector <int> g[3][N];
int size[3][N];
long long sum[3][N];

bool good[3][N];

void dfs(int r, int v, int pr, bool need_sum) {
  int sz = g[r][v].size();
  size[r][v] = 1;
  if (need_sum) {
    sum[r][v] = 0;
  }
  for (int j = 0; j < sz; j++)
    if (g[r][v][j] != pr && good[r][g[r][v][j]]) {
      dfs(r, g[r][v][j], v, need_sum);
      size[r][v] += size[r][g[r][v][j]];
      if (need_sum) {
        sum[r][v] += sum[r][g[r][v][j]] + size[r][g[r][v][j]];
      }
    }
}

void push(int r, int v, int pr) {
  int sz = g[r][v].size();
  for (int j = 0; j < sz; j++)
    if (g[r][v][j] != pr) {
      sum[r][g[r][v][j]] = sum[r][v] - size[r][g[r][v][j]] + (n[r] - size[r][g[r][v][j]]);
      push(r, g[r][v][j], v);
    }
}

long long MAX;

void calc(int r, int v, int pr, int dist, long long x, long long y) {
  long long cur = sum[r][v] * x + dist * y;
  if (cur > MAX) {
    MAX = cur;
  }
  int sz = g[r][v].size();
  for (int j = 0; j < sz; j++)
    if (g[r][v][j] != pr && good[r][g[r][v][j]]) {
      calc(r, g[r][v][j], v, dist + 1, x, y);
    }
}

long long add;

long long a[N], b[N];

void solve(int r, int v, long long n1, long long n2) {
  dfs(r, v, -1, false);
  {
    int tn = size[r][v];
    int pr = -1;
    bool dd = true;
    while (dd) {
      dd = false;
      int sz = g[r][v].size();
      for (int j = 0; j < sz; j++)
        if (g[r][v][j] != pr && good[r][g[r][v][j]]) {
          if (2 * size[r][g[r][v][j]] >= tn) {
            pr = v;
            v = g[r][v][j];
            dd = true;
            break;
          }
        }
    }
  }
  {
    good[r][v] = false;
    int sz = g[r][v].size();
    for (int j = 0; j < sz; j++)
      if (good[r][g[r][v][j]]) {
        MAX = sum[r][v] * n1;
        calc(r, g[r][v][j], -1, 1, n1, n1 * n2);
        a[j] = MAX;
        MAX = sum[r][v] * n2;
        calc(r, g[r][v][j], -1, 1, n2, n1 * n2);
        b[j] = MAX;
      }
    for (int j = 0; j < sz; j++) {
      long long cur = sum[r][v] * n1 + b[j];
      if (cur > add) add = cur;
      cur = sum[r][v] * n2 + a[j];
      if (cur > add) add = cur;
    }
    int k1 = -1, k2 = -1;
    for (int j = 0; j < sz; j++) {
      if (k1 == -1) {
        k1 = j;
      } else
      if (a[j] > a[k1]) {
        k2 = k1;
        k1 = j;
      } else
      if (k2 == -1) {
        k2 = j;
      } else
      if (a[j] > a[k2]) {
        k2 = j;
      }
    }
    for (int j = 0; j < sz; j++) {
      long long cur = b[j];
      if (k1 == j) {
        if (k2 != -1) cur += a[k2];
      } else {
        if (k1 != -1) cur += a[k1];
      }
      if (cur > add) add = cur;
    }
  }
  {
    good[r][v] = false;
    int sz = g[r][v].size();
    for (int j = 0; j < sz; j++)
      if (good[r][g[r][v][j]]) {
        solve(r, g[r][v][j], n1, n2);
      }
  }
}

long long sum_all[3];
long long tot[3];
long long cntn[3];

int main() {
  scanf("%d %d %d", n + 0, n + 1, n + 2);
  for (int r = 0; r < 3; r++) {
    for (int i = 1; i <= n[r] - 1; i++) {
      int foo, bar;
      scanf("%d %d", &foo, &bar);
      g[r][foo].push_back(bar);
      g[r][bar].push_back(foo);
    }
    for (int i = 1; i <= n[r]; i++) good[r][i] = true;
    dfs(r, 1, -1, true);
    push(r, 1, -1);
    sum_all[r] = 0;
    for (int i = 1; i <= n[r]; i++) {
      sum_all[r] += sum[r][i];
    }
    sum_all[r] /= 2;
  }
  long long ans = 0;
  for (int m = 0; m < 3; m++) {
    int x = 0;
    for (int r = 0; r < 3; r++) {
      if (r == m) {
        continue;
      }
      tot[x] = 0;
      for (int i = 1; i <= n[r]; i++)
        if (sum[r][i] > tot[x]) {
          tot[x] = sum[r][i];
        }
      cntn[x] = n[r];
      x++;
    }
    long long s1 = tot[0];
    long long n1 = cntn[0];
    long long s2 = tot[1];
    long long n2 = cntn[1];
    long long out = n[m] * s1 + n[m] * n1;
    out += n[m] * s2 + n[m] * n2;
    out += n1 * s2 + n2 * s1;
    out += n1 * n2 * 2;
    add = 0;
    {
      solve(m, 1, n1, n2);
    }
    if (out + add > ans) {
      ans = out + add;
    }
  }
  cout << ans + sum_all[0] + sum_all[1] + sum_all[2] << endl;
  return 0;
}
View Code

 rng_58:性能

#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <utility>
#include <bitset>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstdio>

using namespace std;

#define REP(i,n) for((i)=0;(i)<(int)(n);(i)++)
#define snuke(c,itr) for(__typeof((c).begin()) itr=(c).begin();itr!=(c).end();itr++)

#define _abs(x) ((x)>0?(x):-(x))
#define eps 1.0E-6
#define PI acos(-1.0)

int N;
int t1[1010],x11[1010],y11[1010],t2[1010],x22[1010],y22[1010];
double x00[1010],y00[1010],vx[1010],vy[1010];
bool meet[1010][1010];
double t[1010][1010];

int most_freq(vector <double> &v){
    int N = v.size();
    int i,j,ans=0;
    sort(v.begin(),v.end());
    
    i = 0;
    while(i < N){
        for(j=i;j<N;j++) if(v[j] - v[i] > eps) break;
        ans = max(ans, j-i);
        i = j;
    }
    
    return ans;
}

int most_freq(vector <pair <double, double> > &v){
    int N = v.size();
    int i,j,k,ans=0;
    sort(v.begin(),v.end());
    
    i = 0;
    while(i < N){
        for(j=i;j<N;j++) if(v[j].first - v[i].first > eps) break;
        
        int tmp = 0;
        vector <double> w;
        for(k=i;k<j;k++) w.push_back(v[k].second);
        sort(w.begin(),w.end());
        REP(k,j-i) if(k == 0 || w[k] - w[k-1] > eps) tmp++;
        
        ans = max(ans, tmp);
        i = j;
    }
    
    return ans;
}

int main(void){
    int i,j;
    
    cin >> N;
    REP(i,N) cin >> t1[i] >> x11[i] >> y11[i] >> t2[i] >> x22[i] >> y22[i];
    
    REP(i,N){
        vx[i] = (double)(x22[i] - x11[i]) / (t2[i] - t1[i]);
        vy[i] = (double)(y22[i] - y11[i]) / (t2[i] - t1[i]);
        x00[i] = x11[i] - vx[i] * t1[i];
        y00[i] = y11[i] - vy[i] * t1[i];
    }
    
    REP(i,N) REP(j,i){
        // point i and point j meet at time t
        double T = 0.0;
        if(_abs(vx[i] - vx[j]) > eps) T = (x00[i] - x00[j]) / (vx[j] - vx[i]);
        if(_abs(vy[i] - vy[j]) > eps) T = (y00[i] - y00[j]) / (vy[j] - vy[i]);
        if(_abs(x00[i] + vx[i] * T - x00[j] - vx[j] * T) < eps && _abs(y00[i] + vy[i] * T - y00[j] - vy[j] * T) < eps){
            meet[i][j] = meet[j][i] = true;
            t[i][j] = t[j][i] = T;
        }
    }
    
    int ans = 1;
    
    REP(i,N){
        vector <double> times;
        REP(j,i) if(meet[i][j]) times.push_back(t[i][j]);
        int tmp = most_freq(times);
        ans = max(ans, tmp + 1);
        
        vector <pair <double, double> > v;
        REP(j,i) if(meet[i][j]){
            double dx = vx[j] - vx[i], dy = vy[j] - vy[i];
            double arg = atan2(dy, dx);
            while(arg < 4.0) arg += PI;
            double speed = cos(arg) * dx + sin(arg) * dy;
            v.push_back(make_pair(arg, speed));
        }
        tmp = most_freq(v);
        ans = max(ans, tmp + 1);
    }
    
    cout << ans << endl;
    
    return 0;
}
View Code

WJMZBMR:google

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <set>
using namespace std;
const int MAX_N = int(1e5) + 10, LOG = 20;
int n, k;
int anc[MAX_N][LOG], dep[MAX_N];
vector<int> E[MAX_N];
int seq[MAX_N], pt, at[MAX_N];

void dfs(int u, int p, int d) {
    anc[u][0] = p, dep[u] = d, seq[pt] = u, at[u] = pt++;
    for (int i = 1; i < LOG; ++i) {
        int go = anc[u][i - 1];
        anc[u][i] = go == -1 ? go : anc[go][i - 1];
    }
    for (vector<int>::iterator e = E[u].begin(); e != E[u].end(); ++e)
        if (*e != p)
            dfs(*e, u, d + 1);
}

int lca(int u, int v) {
    if (dep[u] < dep[v])
        swap(u, v);
    int up = dep[u] - dep[v];
    for (int i = 0; i < LOG; ++i) {
        if (up >> i & 1)
            u = anc[u][i];
    }
    if (u == v)
        return u;
    for (int i = LOG - 1; i >= 0; --i) {
        if (anc[u][i] != anc[v][i])
            u = anc[u][i], v = anc[v][i];
    }
    return anc[u][0];
}

set<int> st;

int add(int u) {
    if (st.empty())
        return 1;
    set<int>::iterator it = st.lower_bound(at[u]);
    int L, R;
    R = seq[it == st.end() ? *st.begin() : *it];
    L = seq[it == st.begin() ? *st.rbegin() : *--it];
    return dep[u] - dep[lca(u, L)] - dep[lca(u, R)] + dep[lca(L, R)];
}

int main() {
    cin >> n >> k;
    for (int i = 0; i < n - 1; ++i) {
        int a, b;
        scanf("%d%d", &a, &b), --a, --b, E[a].push_back(b), E[b].push_back(a);
    }
    dfs(0, -1, 0);
    int j = 0, now = 0; //[i,j)
    int ans = 0;
    for (int i = 0; i < n; ++i) {
        while (now <= k) {
            ans = max(ans, j - i);
            if (j == n)
                break;
            now += add(j), st.insert(at[j]), ++j;
        }
        st.erase(at[i]), now -= add(i);
    }
    cout << ans << endl;
}
View Code

 

幾個原則:spa

1.縮進與空格調試

 關鍵字後面空1格code

 

2.是否換行,是否使用 {}blog

if 和 else ,while等語句後面若只有1行,能夠不用就不要使用{},若比較短就不要換行。

 REP(i,X) REP(j,Y) if(object[i][j] != -1) if(i > 0) for(k=j+1;k<Y;k++) cellmask[i-1][k] |= (1<<object[i][j]);

3.不必define rep for...

for(int i =0; i < MAX_VALUE;++i)

 

4.結構體儘可能使用c風格,重載運算符,在外面重載:

struct Event {
  int x;
  int ya;
  int yb;
  int id;
};

bool operator <(const Event &a, const Event &b) {
  if (a.x != b.x) return a.x < b.x;
  return a.id < b.id;
}
View Code

 

5.cin和scanf能夠混用,輸出看狀況用cout或者printf/puts(C++和C風格不要混用),怎樣打字少就怎樣輸出

 

6.用位移代替* / 2,用 a << 1 | 1代替a * 2 + 1(注意位移運算符的優先級比+-低)

相關文章
相關標籤/搜索