算法竞赛入门经典(第2版)-刘汝佳-第八章例题解题源码(C++语言)(部分)
来源:互联网 发布:ubuntu资源监视器 编辑:程序博客网 时间:2024/06/05 06:16
例题8-1
采用直接构造法,也就是经验方法求解,通过猜想感觉经验求解。没有一个通用的模板。
#include<bits/stdc++.h>using namespace std;const int maxn=100;int pancake[maxn],ans[maxn];int len=0,ansi=0;int flip(int index){int tmp[maxn];for(int i=0;i<=index;i++){tmp[i]=pancake[index-i];}for(int i=0;i<=index;i++){pancake[i]=tmp[i];}} void findmaxnumber(int l,int j){int maxnumber=pancake[0],maxindex=0;for(int i=1;i<l;i++){if(maxnumber<pancake[i]){maxnumber=pancake[i];maxindex=i;}}if(maxindex==0){flip(l-1);ans[ansi++]=len-maxindex;ans[ansi++]=j+1;} else{flip(maxindex);ans[ansi++]=len-maxindex;flip(l-1);ans[ansi++]=j+1;} }bool judge(){int tmp[maxn];memcpy(tmp,pancake,sizeof(pancake));sort(tmp,tmp+len);for(int i=0;i<len;i++){if(pancake[i]!=tmp[i]){return false;}}return true;}int main(){//freopen("datain.txt","r",stdin);//freopen("dataout.txt","w",stdout);string s;while(getline(cin,s)){stringstream ss(s);len=0;ansi=0;int in,flag=0;while(ss>>in){if(flag>0)cout<<" ";pancake[len++]=in;cout<<in;flag++;}cout<<endl;for(int i=0;i<len;i++){if(judge()){ans[ansi++]=0;break;}int l=len-i;findmaxnumber(l,i);}for(int i=0;i<ansi-1;i++){cout<<ans[i]<<" ";}cout<<ans[ansi-1]<<endl;}}
例题8-2
本题目也是采用经验法,进行直接构造。
#include<bits/stdc++.h>using namespace std;int main(){//freopen("datain.txt","r",stdin);//freopen("dataout.txt","w",stdout);int n;while(cin>>n){cout<<"2"<<" "<<n<<" "<<n<<endl;for(int i=0;i<n;i++){for(int j=0;j<n;j++){if(i<26)printf("%c",'A'+i);else{printf("%c",'a'+i-26);}}cout<<endl;}cout<<endl;for(int i=0;i<n;i++){for(int j=0;j<n;j++){if(j<26)printf("%c",'A'+j);else{printf("%c",'a'+j-26);}}cout<<endl;}}return 0;}
例题8-3
本题最好使用hash,但是一直不能设计好hash函数,使用map会超时,而本题使用的存储方式,一定要将fl声明为全局变量,如果是局部变量会报错,编译器不会提供那么大的空间用于存储。因为有大量的数据读入,所以使用ios::sync_with_stdio(false); 关闭同步,增加速度。
#include<bits/stdc++.h>using namespace std;const int maxn=5000;long long fl[4005*4005];int main(){//freopen("datain.txt","r",stdin);//freopen("dataout.txt","w",stdout);ios::sync_with_stdio(false);long long A[maxn],B[maxn],C[maxn],D[maxn];int m,flag=0;cin>>m;while(m--){if(flag){cout<<endl;}int n;cin>>n;long long ans=0;for(int i=0;i<n;i++){cin>>A[i]>>B[i]>>C[i]>>D[i];}int r,c,z;long long len=0;for(int i=0;i<n;i++){for(int j=0;j<n;j++){fl[len++]=A[i]+B[j];}}sort(fl,fl+len);for(int i=0;i<n;i++){for(int j=0;j<n;j++){ans+=upper_bound(fl,fl+len,-C[i]-D[j])-lower_bound(fl,fl+len,-C[i]-D[j]);}}cout<<ans<<endl;flag=1;}return 0;}
例题8-4
枚举超时,枚举代码:
#include<bits/stdc++.h>using namespace std;const int maxn=5000+100;int xl[maxn],xr[maxn],yl[maxn],yr[maxn];int visX[maxn],visY[maxn],n;bool dfsx(int *A,int cur){if(cur==n){return true;}for(int i = xl[cur];i<=xr[cur];i++){if(visX[i]) continue;else{visX[i]=1;A[cur]=i;if(dfsx(A,cur+1)) return true;visX[i]=0;}}return false;}bool dfsy(int *A,int cur){if(cur==n){return true;}for(int i = yl[cur];i<=yr[cur];i++){if(visY[i]) continue;else{visY[i]=1;A[cur]=i;if(dfsy(A,cur+1)) return true;visY[i]=0;}}return false;}int main(){//freopen("datain.txt","r",stdin);//freopen("dataout.txt","w",stdout);while(cin>>n&&n){memset(visX,0,sizeof(visX));memset(visY,0,sizeof(visY));for(int i=0;i<n;i++){cin>>xl[i]>>yl[i]>>xr[i]>>yr[i];}int X[maxn],Y[maxn];if((!dfsx(X,0))||(!dfsy(Y,0)))cout<<"IMPOSSIBLE"<<endl;else{for(int i=0;i<n;i++){cout<<X[i]<<" "<<Y[i]<<endl;}}}return 0;}
所以,本题可以采用贪心策略,因为贪心策略的使用,也只是一种猜想,当然在编程前能证明是最好的。本次采用的贪心策略是先将各区间进行按照xr从小到达排序,xr相等的,xl较小的排在前面。排序后的各点在格子区间里面选择尽量小的数作为自己的行数(列数)。目的是让先选择的车,选择的行(列)对后面的车的选择影响最小。
#include<bits/stdc++.h>using namespace std;const int maxn=5000+100;struct rook{int xl,xr,yl,yr;int id;};rook rooks[maxn],rookssort[maxn];bool cmpx(rook a,rook b){if(a.xr!=b.xr)return a.xr<b.xr; else return a.xl<b.xl;}bool cmpy(rook a,rook b){if(a.yr!=b.yr)return a.yr<b.yr; else return a.yl<b.yl;}int main(){//freopen("datain.txt","r",stdin);//freopen("dataout.txt","w",stdout);int n;while(cin>>n&&n){int ansx[maxn],ansy[maxn],findx=1,findy=1;int visitx[maxn],visity[maxn];memset(visitx,0,sizeof(visitx));memset(visity,0,sizeof(visity));for(int i=0;i<n;i++){rooks[i].id=i;cin>>rooks[i].xl>>rooks[i].yl>>rooks[i].xr>>rooks[i].yr;}sort(rooks,rooks+n,cmpx);for(int i=0;i<n;i++){int flag=0;for(int j=rooks[i].xl;j<=rooks[i].xr;j++){if(!visitx[j]){ansx[rooks[i].id]=j;visitx[j]=1;flag=1;break;}}if(!flag){findx=0;break;}}if(findx){sort(rooks,rooks+n,cmpy);for(int i=0;i<n;i++){int flag=0;for(int j=rooks[i].yl;j<=rooks[i].yr;j++){if(!visity[j]){ansy[rooks[i].id]=j;visity[j]=1;flag=1;break;}}if(!flag){findy=0;break;}}}if(findx&&findy){for(int i=0;i<n;i++){cout<<ansx[i]<<" "<<ansy[i]<<endl;}}elsecout<<"IMPOSSIBLE"<<endl;}return 0;}
例题8-5
本题目通过等价转换后,代码变的简单。将一个大问题变小。
#include<bits/stdc++.h>using namespace std;int main(){int n;while(cin>>n&&n){long long ans=0,a,last=0;for(int i=0;i<n;i++){cin>>a;ans+=abs(last);last+=a;}cout<<ans<<endl;}return 0;}
例题8-6
本题采用极点扫描法,参考了代码仓库的代码,对关键的扫描部分进行了注释。
// UVa1606 Amphiphilic Carbon Molecules// Rujia Liu// To make life a bit easier, we change each color 1 point into color 0.// Then we only need to find an angle interval with most points. See code for details.#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>using namespace std;const int maxn = 1000 + 5;struct Point { int x, y; double rad; // with respect to current point bool operator<(const Point &rhs) const { return rad < rhs.rad; }}op[maxn], p[maxn];int n, color[maxn];// from O-A to O-B, is it a left turn?bool Left(Point A, Point B) { return A.x * B.y - A.y * B.x >= 0;}int solve() { if(n <= 2) return 2; int ans = 0; // pivot point for(int i = 0; i < n; i++) { int k = 0; // the list of other point, sorted in increasing order of rad for(int j = 0; j < n; j++) if(j != i) { p[k].x = op[j].x - op[i].x; p[k].y = op[j].y - op[i].y; if(color[j]) { p[k].x = -p[k].x; p[k].y = -p[k].y; } p[k].rad = atan2(p[k].y, p[k].x); k++; } sort(p, p+k); // sweeping. cnt is the number of points whose rad is between p[L] and p[R] int L = 0, R = 0, cnt = 2; while(L < k) { //注意这个循环体内部cnt不会重置,那么在这个循环中,求解白点的数量,是通过//在相对坐标系中,以原点和p[L]之间的连线作为分割线,以L=0为初始状态,通过扫描的//方法(判断P[R]是否符合要求)计算出左侧白点的数量,当L=1的时候,在L=0时的白点加上符合L=1时分割线的白点,减去//不符合要求的点(实际上只有一个点)。 if(R == L) { R = (R+1)%k; cnt++; } while(R != L && Left(p[L], p[R])) { R = (R+1)%k; cnt++; } //增加符合要求的点 cnt--;//减去不符合要求的白点。 L++; ans = max(ans, cnt); } } return ans;}int main() {freopen("datain.txt","r",stdin); while(scanf("%d", &n) == 1 && n) { for(int i = 0; i < n; i++) scanf("%d%d%d", &op[i].x, &op[i].y, &color[i]); printf("%d\n", solve()); } return 0;}
例题8-7
本题使用两种方法,进行求解。算法复杂度相同,引入了滑动窗口的概念。
第一种:
#include<bits/stdc++.h>using namespace std;const int maxn = 1000000+5;int A[maxn];int main(){int T,n;scanf("%d",&T);while(T--){scanf("%d",&n);for(int i=0;i<n;i++) scanf("%d",&A[i]);set<int> s;int L=0,R=0,ans=0;while(R<n){while(R<n&&!s.count(A[R])) s.insert(A[R++]);ans = max(ans,R-L);s.erase(A[L++]);}printf("%d\n",ans);}return 0;}
第二种:滑动窗口
#include<bits/stdc++.h>using namespace std;int A[maxn],last[maxn];map<int,int> cur;int main(){int T,n;scanf("%d",&T);while(T--){scanf("%d",&n);cur.clear();for(int i=0;i<n;i++){scanf("%d",&A[i]);if(!cur.count(A[i])) last[i]=-1;else last[i] = cur[A[i]];//上一个相同元素的下标 。 cur[A[i]] = i;}int L=0,R=0,ans=0;while(R<n){while(R<n&&last[R]<L) R++;//判断是否A[R]元素是否在[L,R]中,如果在就停止。 ans = max(ans,R-L);L++;}printf("%d\n",ans);}return 0;}
例题8-8
本题基本采用等价转化的思想,并使用set来进行实现。本题列出代码仓库的代码。
// UVa1471 Defense Lines// Rujia Liu// Algorithm 1: use STL set to maintain the candidates.// This is a little bit more intuitive, but less efficient (than algorithm 2)#include<cstdio>#include<set>#include<cassert>using namespace std;const int maxn = 200000 + 5;int n, a[maxn], f[maxn], g[maxn];struct Candidate {int a, g;Candidate(int a, int g):a(a),g(g) {}bool operator < (const Candidate& rhs) const {return a < rhs.a;}};set<Candidate> s;int main() {freopen("datain.txt","r",stdin);int T;scanf("%d", &T);while(T--) {scanf("%d", &n);for(int i = 0; i < n; i++)scanf("%d", &a[i]);if(n == 1) { printf("1\n"); continue; }// g[i] is the length of longest increasing continuous subsequence ending at ig[0] = 1;for(int i = 1; i < n; i++)if(a[i-1] < a[i]) g[i] = g[i-1] + 1;else g[i] = 1;// f[i] is the length of longest increasing continuous subsequence starting from if[n-1] = 1;for(int i = n-2; i >= 0; i--)if(a[i] < a[i+1]) f[i] = f[i+1] + 1;else f[i] = 1;s.clear();s.insert(Candidate(a[0], g[0]));int ans = 1;for(int i = 1; i < n; i++) {Candidate c(a[i], g[i]);set<Candidate>::iterator it = s.lower_bound(c); // first one that is >= cbool keep = true;if(it != s.begin()) {Candidate last = *(--it); // (--it) points to the largest one that is < cint len = f[i] + last.g;ans = max(ans, len);s.insert(c);}if(keep) {s.erase(c); // if c.a is already present, the old g must be <= c.git = s.find(c); // this is a bit cumbersome and slow but it's clearit++;while(it != s.end() && it->a > c.a && it->g <= c.g) s.erase(it++);}}printf("%d\n", ans);}return 0;}
例题8-9
本题目参考书中解答和代码仓库。
// UVa1451 Average// Rujia Liu#include<cstdio>using namespace std;const int maxn = 100000 + 5;int n, L;char s[maxn];int sum[maxn], p[maxn]; // average of i~j is (sum[j]-sum[i-1])/(j-i+1)// compare average of x1~x2 and x3~x4int compare_average(int x1, int x2, int x3, int x4) { return (sum[x2]-sum[x1-1]) * (x4-x3+1) - (sum[x4]-sum[x3-1]) * (x2-x1+1);}int main() { int T; scanf("%d", &T); while(T--) { scanf("%d%d%s", &n, &L, s+1); sum[0] = 0; for(int i = 1; i <= n; i++) sum[i] = sum[i-1] + s[i] - '0'; int ansL = 1, ansR = L; // p[i..j) is the sequence of candidate start points int i = 0, j = 0; for (int t = L; t <= n; t++) { // end point while (j-i > 1 && compare_average(p[j-2], t-L, p[j-1], t-L) >= 0) j--; // remove concave points p[j++] = t-L+1; // new candidate while (j-i > 1 && compare_average(p[i], t, p[i+1], t) <= 0) i++; // update tangent point // compare and update solution int c = compare_average(p[i], t, ansL, ansR); if (c > 0 || c == 0 && t - p[i] < ansR - ansL) { ansL = p[i]; ansR = t; } } printf("%d %d\n", ansL, ansR); } return 0;}
例题8-10
本题目采用的二分法和贪婪算法结合,通过二分法找到最大值尽量小的那个数,在通过贪心法从右向左尽量搜索,每个子序列在小于找到的那个数的情况,尽量长。这样就能保证S(1)尽量小,满足条件。
#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn=600;ll m,k,p[maxn],slash[maxn];;bool judge(ll mid,ll& maxnum){for(int i=0;i<k;i++){int j=slash[i]-1;ll sum=p[j];slash[i+1]=j;for(j=j-1;j>=k-i-1;j--){if(i!=k-1){if(sum+p[j]<=mid){sum+=p[j];slash[i+1]=j;}else{break;}}else{sum+=p[j];slash[i+1]=j;}}maxnum=max(maxnum,sum);}if(maxnum<=mid) return true;else return false;}ll bsearch(ll x,ll y){ll mid;slash[0]=m;while(x<y){mid=x+(y-x)/2;ll maxnum=0; if(judge(mid,maxnum)) y=maxnum;else x=mid+1;}return x;}int main(){//freopen("datain.txt","r",stdin);//freopen("dataout.txt","w",stdout);int T;cin>>T;while(T--){ll lb=0,ub=0,mid,maxnum=0;cin>>m>>k;for(int i=0;i<m;i++){cin>>p[i];ub+=p[i];}mid = bsearch(lb,ub);judge(mid,maxnum);int j=k-1;for (int i=0;i<m-1;i++){if(i==slash[j]&&j>0){cout<<"/"<<" ";j--;}cout<<p[i]<<" ";}if(slash[j]==m-1&&j>0){cout<<"/"<<" ";j--;}cout<<p[m-1]<<endl;}return 0;}
例题8-11
贪心算法,每次选择最小的两个数进行相加,并将他们的和压入优先队列。
#include<bits/stdc++.h>using namespace std;const int maxn=6000;int main(){//freopen("datain.txt","r",stdin);//freopen("dataout.txt","w",stdout);int n;while(cin>>n&&n){int tmp;priority_queue<int, vector<int>,greater<int>> q;for(int i=0;i<n;i++){cin>>tmp;q.push(tmp);}int ans = 0;for(int i=0;i<n-1;i++){int a = q.top();q.pop();int b = q.top();q.pop();ans+=a+b;q.push(a+b);}cout<<ans<<endl;}return 0;}
习题8-12
我开始并没有使用提供的方法,我们可以发现规律,第k小时第i行。i>2^(k-1)的时候,红气球数量等于第k-1小时第i行的红气球数量,如果i<=2^(k-1)时,红气球数量等于第k-1小时第i行的红气球数量的2倍。这样求出每行再累加起来就可以得到答案。时间复杂度为O(k*(b-a)).经过UVa测试,LTE超时,还是不得不使用书中O(k)的思路。
第一种:TLE
#include<bits/stdc++.h>using namespace std;typedef long long ll;ll cntr(ll k, ll a){if(k==0) return 1;else if(a>(1<<(k-1))) {return cntr(k-1, a-(1<<(k-1)));}else{return cntr(k-1, a)*2;}}int main(){//freopen("datain.txt","r",stdin);//freopen("dataout.txt","w",stdout);int T,rnd=1;cin>>T;while(T--){ll k,a,b;ll sum=0;cin>>k>>a>>b;for(ll i=a;i<=b;i++){sum+=cntr(k,i);}cout<<"Case "<<rnd++<<": "<<sum<<endl;}return 0;}
第二种:
通过求解书中的f函数或者g函数都能求解,下面以g函数为例。本题使用了递推。
#include<bits/stdc++.h>using namespace std;long long c(int k) { return k == 0 ? 1 : c(k - 1) * 3; } long long g(int k, int i) { if (i == 0) { return 0; } if (k == 0) { return 1; } int k2 = 1 << (k - 1); if (i >= k2) { return 2 * g(k - 1, i - k2) + c(k - 1); } else { return g(k - 1, i); } } int main() { //freopen("datain.txt","r",stdin);//freopen("dataout.txt","w",stdout); ios::sync_with_stdio(false); int T; cin >> T; int kase = 0; while (T--) { int k, a, b; cin >> k >> a >> b; cout << "Case " << ++kase << ": "; cout << g(k, (1 << k) - a + 1) - g(k, (1 << k) - b) << endl; } return 0; }
例题8-13
模拟法,主要是要从中挖掘和分析出一些限制条件,避免没有必要的枚举,节省时间。
#include<bits/stdc++.h>using namespace std;typedef long long ll;const ll maxn=100010;int ps[maxn],qs[maxn];int main(){//freopen("datain.txt","r",stdin);//freopen("dataout.txt","w",stdout);int T,rnd=1;cin>>T;while(T--){cout<<"Case "<<rnd++<<": ";ll n;cin>>n;for(ll i=0;i<n;i++) cin>>ps[i];for(ll i=0;i<n;i++) cin>>qs[i];int su=1;for(ll i=0;i<n;)//以i加油站作为起点。 {ll j=i,gas=0,cnt=0,flag=0;while(cnt<n){gas+=ps[j];if(gas>=qs[j]){gas-=qs[j++];if(j == n){j %= n;flag = 1;}//表示已经遍历了N个点,如果能够成功那么cnt==n//如果失败,那么证明以i...n作为起点也不会成功 cnt++;}else{i = j+1;break;}}if(cnt == n){cout<<"Possible from station "<<i+1<<endl;su=0;break;}if(flag){cout<<"Not possible"<<endl;su=0;break;} }if(su)cout<<"Not possible"<<endl;}return 0;}
例题8-14
本题目自己对题意理解不深,使用的是代码仓库的代码,以供参考。
// UVa1607 Gates// Rujia Liu#include<cstdio>#include<algorithm>using namespace std;const int maxm = 200000 + 5;int n, m;struct Gates { int a, b, o;} gates[maxm];// returns the output of input 000..0111...1 (there are k 0's)int output(int k) { for(int i = 1; i <= m; i++) { int a = gates[i].a; int b = gates[i].b; int va = a < 0 ? -a > k : gates[a].o; int vb = b < 0 ? -b > k : gates[b].o; gates[i].o = !(va && vb); } return gates[m].o;}// returns k such that // 1. output(k) = output(n)// 2. output(k-1) = output(0)int solve(int vn) { int L = 1, R = n; while(L < R) { int M = L + (R-L)/2; if(output(M) == vn) R = M; else L = M+1; } return L;}int main() { int T; scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); for (int i = 1; i <= m; i++) scanf("%d%d", &gates[i].a, &gates[i].b); int v0 = output(0); int vn = output(n); if(v0 == vn) { for(int i = 1; i <= n; i++) printf("0"); } else { int x = solve(vn); for(int i = 1; i < x; i++) printf("0"); printf("x"); for(int i = x+1; i <= n; i++) printf("1"); } printf("\n"); } return 0;}
例题8-15
本题通过滑动窗口加枚举的方式,总的而言,主要是枚举那边理解有些困难,其他还好。
代码参考:点击打开链接
#include<iostream> #include<cstring>#include<set>using namespace std;const int N = 1e5 + 5;int s, n, a[N], vis[N];bool flag[N];int ans;void init() { cin >> s >> n; int num = 0; for (int i = 0; i < n; i++) { cin >> a[i]; if (i < s) { //对前面的s个进行分析 if (vis[a[i]]) num++; //统计前s个中重复的数字 vis[a[i]]++; } } for (int i = 0; i < n; i++) { //如果num=0,说明前s个中没有重复的数字,那么第一个数字可以作为循环的开始 if (num == 0) flag[i] = true; //窗口开始滑动 if (vis[a[i]] == 2) num--; //如果此时最左边的数为重复了的数,num需要减1 vis[a[i]]--; int k = i + s; //新数字进入滑动窗口 if (k >= n) continue; if (vis[a[k]]) num++; //如果已经出现过 vis[a[k]]++; }}bool judge(int x) { for (int i = x; i < n; i += s) if (!flag[i]) return false; return true;}void solve() { memset(vis, 0, sizeof(vis)); ans = 0; for (int i = 0; i < s; i++) { if (judge(i)) ans++; if (i >= n) continue; //从左往右依次遍历,如果当前a[i]前面已经出现过,那么前面必须会有开头,此时必须结束循环 if (vis[a[i]]) break; vis[a[i]]++; }}int main() { //freopen("D:\\txt.txt", "r", stdin); int t; cin >> t; while (t--) { memset(flag, 0, sizeof(flag)); memset(vis, 0, sizeof(vis)); init(); solve(); cout << ans << endl; } return 0;}
例题8-16
本题目按照书中的方法,没有问题,这里参考了代码仓库的代码,并进行了注释,便于学习。
#include<cstdio>#include<map>using namespace std;const int maxn = 200000 + 5;int A[maxn], prev[maxn], next[maxn];map<int, int> cur;inline bool unique(int p, int L, int R) { return prev[p] < L && next[p] > R; //如果与在p位置的元素相等的前一个元素的位置小于L,后一个元素位置大于R。 //则说明在这个子序列中唯一。 }bool check(int L, int R) { if(L >= R) return true; for(int d = 0; L+d <= R-d; d++) { //从头开始找,尝试第一个元素是不是唯一 if(unique(L+d, L, R)) return check(L, L+d-1) && check(L+d+1, R); //如果子序列没有唯一元素,返回false if(L+d == R-d) break; //从头开始找,尝试最后一个元素是不是唯一 if(unique(R-d, L, R)) return check(R-d+1, R) && check(L, R-d-1); //如果子序列没有唯一元素,返回false } return false;//如果没有唯一元素,返回false. }int main() {//freopen("datain.txt","r",stdin); int T, n; scanf("%d", &T); while(T--) { scanf("%d", &n); cur.clear(); for(int i = 0; i < n; i++) { scanf("%d", &A[i]); if(!cur.count(A[i])) prev[i] = -1;//如果A[i]没有出现过,则赋值为1. else prev[i] = cur[A[i]];//如果出现过,则将前一个的索引存入pre。 cur[A[i]] = i;//保存A[i]的索引i。 } cur.clear(); //同理找到后一个相等元素的位置 for(int i = n-1; i >= 0; i--) { if(!cur.count(A[i])) next[i] = n; else next[i] = cur[A[i]]; cur[A[i]] = i; } if(check(0, n-1)) printf("non-boring\n"); else printf("boring\n"); } return 0;}
- 算法竞赛入门经典(第2版)-刘汝佳-第八章例题解题源码(C++语言)(部分)
- 算法竞赛入门经典(第2版)-刘汝佳-第九、十一章例题解题源码(C++语言)(部分)
- 算法竞赛入门经典(第2版)-刘汝佳-第四章解题源码(C语言)(部分)
- 算法竞赛入门经典(第2版)-刘汝佳-第三章解题源码(C语言)
- 算法竞赛入门经典(第2版)-刘汝佳-第五章解题源码(C++语言)(部分)
- 算法竞赛入门经典(第2版)-刘汝佳-第六章解题源码(C++语言)(部分)
- 算法竞赛入门经典(第2版)-刘汝佳-第七章解题源码(C++语言)(部分)
- 算法竞赛入门经典(第二版) 刘汝佳-第八章 高效算法设计 例题(13/19)
- 算法竞赛入门经典(第2版)-刘汝佳-解题源码说明
- 算法竞赛入门经典(第二版)第2章部分学习实现
- 算法竞赛入门经典第6章例题(2):二叉树部分+四分树
- 《算法竞赛入门经典》刘汝佳 C语言部分(前四章)“注解与习题” 之思索 <1>
- 《算法竞赛入门经典(第2版)》刘汝佳读后感
- 算法竞赛入门经典(第二版)-刘汝佳-第五章 C++与STL 例题(9/12)
- 算法竞赛入门经典(第二版)-刘汝佳-第六章 数据结构基础 例题(17/22)
- 算法竞赛入门经典(第二版)-刘汝佳-第七章 暴力求解法 例题(6/15)
- 算法竞赛入门经典(第二版)-刘汝佳-第九章 动态规划初步 例题(11/31)
- 算法竞赛入门经典(第二版)第3章部分学习实现(上)
- win7+64位系统中搭建mongodb数据库运行环境
- 如何将eclipse上的项目快速的转到androidstudio上
- frame 嵌套页面定位元素方法
- CAD工程图纸转jpg格式教程
- 设计模式小记(一)
- 算法竞赛入门经典(第2版)-刘汝佳-第八章例题解题源码(C++语言)(部分)
- 14 外连接(hash join outer)--优化主题系列
- Leetcode [Valid Parentheses]
- Jetty Tomcat
- DBCP与C3P0
- 微信退款结果通知
- tensorboard
- Shell脚本里面 $#, $@的含义
- Azure Linux 虚拟机常见导致无法远程的操作