1~10 2014年9月1日 看来以后用cpp比java要舒服的多~话说第一次这么长的写cpp。还是比较喜欢的,看来语言是工具一点也不假。虽然很多题目以前打过了数遍,还是多实践,细节方面更加优美,话说编程艺术之美系列的文章也在同步看,感觉不错~应该是三个月没有碰代码以至于自己很多写过的题都打不出来。囧。共勉吧
/* 区间问题,贪心策略:结束的越早,可选的工作就越多。 5 1 3 2 5 4 7 6 9 8 10 3 */ #include<iostream> using namespace std; const int MAXN=1<<7; int n,s[MAXN],t[MAXN]; pair<int,int> st[MAXN]; void input(){ scanf("%d",&n); int i=0; while(i<n){ scanf("%d %d",&s[i],&t[i]); i++; } } void sovle(){ for(int i=0;i<n;i++){ st[i].first=t[i]; st[i].second=s[i]; } sort(st,st+n); int ans=0; int t=0;//结束的时间 for(int i=0;i<n;i++){ if(t<st[i].second){ ans++; t=st[i].first; } } printf("%d\n",ans); } int main(){ input(); sovle(); return 0; }
/* CN已经排序,从小到大 依序枚举 注意是否够=min(A/CN[i],C[i]),尼玛solve1自己写的太坑了,冗余性大 3 2 1 3 0 2 620 6 */ #include<iostream> using namespace std; const int MAXN=1<<4; int C[MAXN],A=0,n; int CN[6]={1,5,10,50,100,500}; void input(){ int i=0; char ln; while(1){ scanf("%d",&C[i++]); scanf("%c",&ln); if(ln=='\n') break; } i--; A=C[i]; n=i; } void sovle1(){ int cnt=0,j=0; for(int i=n-1;i>=0;i--){ if(CN[i]<=A){ j=A/CN[i]; if(j>C[i])j=C[i]; A-=(j*CN[i]); cnt+=j; //printf("%d %d\n",A,CN[i]); } if(A==0){ printf("%d\n",cnt); break; } } } void sovle2(){ int ans=0,j; for(int i=n-1;i>=0;i--){ ans+=(j=min(A/CN[i],C[i])); A-=j*CN[i]; } printf("%d\n",ans); } int main(){ input(); //sovle1(); sovle2(); }
/* BFS遍历:从起点坐标(sx,sy)向四个方向BFS (取出队列顶部,非终点,该元素未四个方向加入队列,更新d,直至循环队列为空,得到d[gx][gy]就是最短路径) maze[MAXN][MAXN]迷宫 d[MAXN][MAXN]距离起点S的距离 10 10 #S######.# ......#..# .#.##.##.# .#........ ##.##.#### ....#....# .#######.# ....#..... .####.###. ....#...G# */ #include<iostream> #include<queue> using namespace std; const int MAXN=1<<7; const int INF=100000000; int sx,sy,gx,gy; int N,M,d[MAXN][MAXN]; char maze[MAXN][MAXN]; int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1}; typedef pair<int,int> P; void input(){ scanf("%d",&N); scanf("%d",&M); for(int i=0;i<N;i++) scanf("%s",&maze[i]); for(int i=0;i<N;i++) for(int j=0;j<M;j++){ d[i][j]=INF; if(maze[i][j]=='S'){sx=i;sy=j; } if(maze[i][j]=='G'){gx=i;gy=j; } } //sx=0,sy=1,gx=9,gy=8; } int bfs(){ queue<P>que; que.push(P(sx,sy)); //初始化,起点加入队列 ,d起点初始化0 d[sx][sy]=0; while(que.size()){ //取出队列首部 P p=que.front(); que.pop(); //判断是终点返回 if(p.first==gx&&p.second==gy) break; //四个方向bfs for(int i=0;i<4;i++){ int nx=p.first+dx[i],ny=p.second+dy[i]; //未访问符合条件的位置加入队列,更新d if(0<=nx&&nx<N&&0<=ny&&ny<M&&maze[nx][ny]!='#'&& d[nx][ny]==INF){ que.push(P(nx,ny)); d[nx][ny]=1+d[p.first][p.second]; } } } return d[gx][gy]; } void sovle(){ int ans=bfs(); printf("%d\n",ans); } int main(){ input(); sovle(); return 0; }
/* 枚举每个位置dfs改变访问的w为.状态。 统计枚举次数 注意dfs中的访问边界 N*M 10 12 w........ww. .www.....www ....ww...ww. .........ww. .........w.. ..w......w.. .w.w.....ww. w.w.w.....w. .w.w......w. ..w.......w. 3 */ #include<iostream> using namespace std; const int MAXN=1<<7; char a[MAXN][MAXN]; int N,M; int cnt=0; void input(){ scanf("%d",&N); scanf("%d",&M); for(int i=0;i<N;i++){ scanf("%s",&a[i]); } } void dfs(int x,int y){ a[x][y]='.'; cnt++; for(int dx=-1;dx<=1;dx++) for(int dy=-1;dy<=1;dy++){ int nx=x+dx,ny=y+dy; if(0<=nx&&nx<N&&0<=ny&&ny<M&&a[nx][ny]=='w') //访问边界 dfs(nx,ny); } return; } void sovle(){ int ans=0; for(int i=0;i<N;i++) for(int j=0;j<M;j++){ if(a[i][j]=='w'){ printf("%d %d\n",i,j); dfs(i,j); ans++; } } printf("%d\n",ans); printf("%d\n",cnt); } int main(){ input(); sovle(); return 0; }
/* DFS dfs(int i,int sum)//i时候的累积代价为sum。不具有dp的最优结构 4 1 2 4 7 13 YES(13=2+4+7) 4 1 2 4 7 15 No */ #include<iostream> const int MAXN=1<<7; int a[MAXN],n,k; void input(){ scanf("%d",&n); int i=0; while(i<n){ scanf("%d",&a[i++]); } scanf("%d",&k); } //i项之前的sum,i项之后进行分支 bool dfs(int i,int sum){ if(i==n) return sum==k; //不选a[i] if(dfs(i+1,sum)) return true; //选择 if(dfs(i+1,sum+a[i])) return true; return false; } int main(){ input(); if(dfs(0,0)==true) printf("Yes\n"); else printf("No\n"); return 0; }
/* STL练习 */ #include<cstdio> #include<stack> #include<queue> using namespace std; void stack_t(){ stack<int> s; s.push(1); s.push(2); s.push(3); printf("%d\n",s.top()); s.pop(); printf("%d\n",s.top()); } void queue_t(){ queue<int> q; q.push(1); q.push(2); printf("%d\n",q.front()); printf("%d\n",q.back()); q.pop(); printf("%d\n",q.front()); } int main(){ stack_t(); printf("-----------\n"); queue_t(); return 0; }
/* 记忆化存储 */ #include<iostream> using namespace std; const int MAXN=1<<7; int n,memo[MAXN]; int fib(int n){ if(n<=1) return n; if(memo[n]!=0) return memo[n]; return memo[n]=(fib(n-1)+fib(n-2)); } int main(){ scanf("%d",&n); printf("%d\n",fib(n)); }
/* sovle1枚举所有方案 3 10 1 3 5 3 9 1 3 5 Yes No */ #include<iostream> #include<time.h> using namespace std; const int MAXN=1<<10; int n,m,k[MAXN],kk[MAXN],i=0; void input(){ scanf("%d",&n); scanf("%d",&m); while(i<n){ scanf("%d",&k[i++]); } } //n^4算法 void sovle1(){ for(int a =0;a<n;a++) for(int b =0;b<n;b++) for(int c= 0;c<n;c++) for(int d= 0;d<n;d++) if(m==(k[a]+k[b]+k[c]+k[d])){ printf("YES\n"); return; } printf("No\n"); } bool bs(int x){ int l=0,r=n; while(l<r){ int mid=(l+r)/2; if(k[mid]==x) return true; else if(x<k[mid]) r=mid-1; else l=mid+1; } return false; } bool bs2(int x){ int l=0,r=n*n; while(l<r){ int mid=(l+r)/2; if(kk[mid]==x) return true; else if(x<kk[mid]) r=mid-1; else l=mid+1; } return false; } //n^3logn void sovle2(){ //排序k sort(k,k+n); for(int a =0;a<n;a++) for(int b =0;b<n;b++) for(int c= 0;c<n;c++) if(bs(m-(k[a]+k[b]+k[c]))){ printf("YES\n"); return; } printf("No\n"); } //n^2logn void sovle3(){ //排序kk for(int c= 0;c<n;c++) for(int d= 0;d<n;d++) kk[n*c+d]=k[c]+k[d]; sort(kk,kk+n*n); for(int a =0;a<n;a++) for(int b =0;b<n;b++) if(bs2(m-(k[a]+k[b]))){ printf("YES\n"); return; } printf("No\n"); } int main(){ input(); clock_t t=clock(); sovle1(); printf("sovle1=%d\n",clock()-t); sovle2(); printf("sovle2=%d\n",clock()-t); sovle3(); printf("sovle3=%d\n",clock()-t); return 0; }
/* Ants不做区分。 最短时间:计算所有蚂蚁的最短距离的最大值 最长时间:计算所有蚂蚁的最长距离的最大值 10 3 2 6 7 4 8 */ #include<iostream> using namespace std; int L=0,n=0,a[1<<10],i=0; void input(){ scanf("%d",&L); scanf("%d",&n); while(i<n) scanf("%d",&a[i++]); } void sovle(){ int MinT=0; for(i=0;i<n;i++){ //枚举求出最小 MinT=max(MinT,min(a[i],L-a[i])); } int MaxT=0; for(i=0;i<n;i++){//枚举求出最大 MaxT=max(MaxT,max(a[i],L-a[i])); } printf("%d %d",MinT,MaxT); } int main(){ input(); sovle(); return 0; }
/* 枚举所有边n3复杂度 max出最大边, 充要条件:周长减去最大边的值大于最大边 */ #include <iostream> using namespace std; int n,a[1<<7],i,j,k; void input(){ scanf("%d",&n); while(i<n){ scanf("%d",&a[i++]); } } void sovle(){ int ans=0; for(i=0;i<n;i++) for(j=i+1;j<n;j++) for(k=j+1;k<n;k++){ int len=a[i]+a[j]+a[k]; int ma=max(a[i],max(a[j],a[k])); int rest=len-ma; if(ma<rest) ans=max(ans,len); } printf("%d\n",ans); } int main(){ input(); sovle(); return 0; } /* 5 2 3 4 5 10 4 4 5 10 20 12 0 */