由于算法题一般都有6k最大文件限制,又要节约打字时间又要追求效率和准确率,和工程的要求有很大的不同。所以尽量要使用简洁的风格。

之前是和工程一样严格遵循google C++编程规范,浪费了apm的调试还容易出错,写出的程序性能还不高比别人的难看代码多上百ms。为了提高准确率,我要一改以前的迂腐作风,不到200行的程序讲究什么编程规范。我仔细研究了曾经的top coder NO.1 Petr的第一视角,要找出一种最有效的代码风格:

SRM 529

 codeforces NO.1 tourist的代码:

#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:

#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

 

几个原则:

1.缩进与空格

 关键字后面空1格

 

2.是否换行,是否使用 {}

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(注意位移运算符的优先级比+-低)