由于算法题一般都有6k最大文件限制,又要节约打字时间又要追求效率和准确率,和工程的要求有很大的不同。所以尽量要使用简洁的风格。
之前是和工程一样严格遵循google C++编程规范,浪费了apm的调试还容易出错,写出的程序性能还不高比别人的难看代码多上百ms。为了提高准确率,我要一改以前的迂腐作风,不到200行的程序讲究什么编程规范。我仔细研究了曾经的top coder NO.1 Petr的第一视角,要找出一种最有效的代码风格:
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; }
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; }
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; }
几个原则:
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; }
5.cin和scanf可以混用,输出看情况用cout或者printf/puts(C++和C风格不要混用),怎样打字少就怎样输出
6.用位移代替* / 2,用 a << 1 | 1代替a * 2 + 1(注意位移运算符的优先级比+-低)
总想把每一篇文章精雕细琢之后以完美的面貌示人,就像演员在演出前都要彩排,总想准备好之后再去展现精彩的一面,但人生的每一刻都是精彩的,就算现在还不完善也要发出来,作为自己一直在学习的一种见证。