赞
踩
越来越不想写博客了。。。。但适当总结是很必要的。
1.深搜和广搜当有多组样例时,注意全局变量的清0和更新,还有数组和标记数组都要清0!!
2.数组标记用了不会错,不用可能超时,尽量都用。
3.一种通过递归记录路径的方法真实太妙了!!虽然我用的广搜的模板,但这个记录路径的方法有深搜的影子,很妙。
https://www.luogu.com.cn/problem/P6207
#include <bits/stdc++.h> using namespace std; struct node { int x,y,s; }; int dx[4]={0,0,1,-1}; int dy[4]={1,-1,0,0}; int r,c,vis[200][200],dist[200][200][2],k; char a[200][200]; queue<node>q; void bfs() { vis[1][1]=1; node cur,nxt; cur.x=1;cur.y=1;cur.s=0; q.push(cur); while(!q.empty()) { cur=q.front();q.pop(); if(cur.x==r&&cur.y==c) return ; for(int i=0;i<4;i++) { nxt.x=cur.x+dx[i]; nxt.y=cur.y+dy[i]; if(a[nxt.x][nxt.y]=='.'&&vis[nxt.x][nxt.y]==0&&nxt.x>=1&&nxt.x<=r&&nxt.y>=1&&nxt.y<=c) { nxt.s=cur.s+1;vis[nxt.x][nxt.y]=1;q.push(nxt); dist[nxt.x][nxt.y][0]=cur.x; dist[nxt.x][nxt.y][1]=cur.y; } } } } void print(int x,int y) { if(!(dist[x][y][0]+dist[x][y][1])) return; print(dist[x][y][0],dist[x][y][1]); printf("%d %d\n",x,y); } int main() { scanf("%d%d",&r,&c); for(int i=1;i<=r;i++) for(int j=1;j<=c;j++) cin>>a[i][j]; bfs(); puts("1 1"); print(r,c); return 0; }
4.用while构造不同进制,统计不同进制下的波浪数,卡了我好久,就是想不明白,虽然用到的思想知识构造,捎带一点进位转换。。。
https://www.luogu.com.cn/problem/P1112
#include <bits/stdc++.h> using namespace std; int a,b,c,d,k,f[50],q[10000005],sum,t; void go(int x) { for(int i=1;i<x;i++) { for(int j=0;j<x;j++) { if(i!=j) { sum=0;t=0; while(sum<=d) { if(t%2==0) { sum=sum*x+i;t++; } else { sum=sum*x+j;t++; } if(sum>=c&&sum<=d) q[sum]++; } } } } } int main() { cin>>a>>b>>c>>d>>k; for(int i=a;i<=b;i++) go(i); for(int i=c;i<=d;i++) { if(q[i]==k) cout<<i<<endl; } return 0; }
5.next_permutation 函数的使用,列出全排列,基本代码格式:
int main() {
string str; //字符串的全排列
cin>>str;
sort(str.begin(),str.end());
do{
cout<<str<<endl;
}while(next_permutation(str.begin(),str.end()));
return 0;
}
6.杨辉三角的参数计算,这种深搜到的方式掌握的并不好
https://www.luogu.com.cn/problem/P1118
#include <bits/stdc++.h> using namespace std; int pc[50],n; int main() { cin>>n; //输入n,算的是C(0到n-1,n-1)的排列 pc[0]=pc[n-1]=1; if (n>1) for (int i=1;i*2<n;i++) pc[i]=pc[n-1-i]=(n-i)*pc[i-1]/i;//杨辉三角的对称性 for(int i=0;i<n;i++) cout<<pc[i]<<" "; cout<<endl; return 0; }
#include <bits/stdc++.h> using namespace std; int pc[50],n,k,vis[50],ans[50],sum; int dfs(int i,int num,int sum) //枚举第i个数,第i个数是什么,当前和sum { if(sum>k) return 0; if(i==n) { if(sum==k) { ans[i]=num;return 1; } else return 0; } vis[num]=1; for(int j=1;j<=n;j++) { if(!vis[j]&&dfs(i+1,j,sum+pc[i]*j)) { ans[i]=num;return 1; } } vis[num]=0; return 0; } int main() { cin>>n>>k; //输入n,算的是C(0到n-1,n-1)的排列 pc[0]=pc[n-1]=1; if (n>1) for (int i=1;i*2<n;i++) pc[i]=pc[n-1-i]=(n-i)*pc[i-1]/i;//杨辉三角的对称性 if(dfs(0,0,0)) for(int i=1;i<=n;i++) cout<<ans[i]<<" "; cout<<endl; return 0; }
7.学到一种新的找最长回文字符串的方式。遍历每个字符,通过长度的奇偶比较返回大的那个值。本题从格式处理上增加了难度。
#include <bits/stdc++.h> using namespace std; const int maxn=20005; char s[maxn],s1[maxn]; int pos[maxn],n,l,t,mn1,ls; int check(int x) { int a1=1,a2=0; for(int i=x,j=1;i-j>=0&&i+j<l&&s1[i-j]==s1[i+j];j++) //奇数从1开始 a1+=2; for(int i=x,j=0;i-j>=0&&i+j+1<l&&s1[i-j]==s1[i+j+1];j++) //偶数从0开始 a2+=2; return max(a1,a2); } int main() { while((s[n]=getchar())!=EOF) n++; for(int i=0;i<n;i++) { if(isalpha(s[i])) { s1[l]=tolower(s[i]); pos[l++]=i; //提取的字符所在位置 } } for(int i=0;i<l;i++) { t=check(i); if(t>mn1) { mn1=t; ls=i+(t/2); } } s[pos[ls]+1]='\0'; printf("%d\n%s\n",mn1,&s[pos[ls-mn1+1]]); return 0; }
8.并查集的题目,算作复习一下,用结构体存一直通不过,改为数组存数据就通过了。
啊啊啊啊啊,是我的代码出问题了,有时因为一个下标写错检查半天,我还怀疑是结构体的存储方式出问题了。。。。。我想一头撞死
https://www.luogu.com.cn/problem/P3144
#include <bits/stdc++.h> using namespace std; struct node { int l,r; }e[3005]; int f[3005],n,m,ans,p[3005],q[3005]; int r_find(int r) { while(r!=f[r]) r=f[r]; return r; } void init() { for(int i=1;i<=n;i++) f[i]=i; return; } void mg(int x,int y) { int fx,fy; fx=r_find(x);fy=r_find(y); if(fx!=fy) f[fx]=fy; } int check() { int k=0; for(int i=1;i<=n;i++) { if(q[i]==1) continue; if(f[i]==i) k++; } if(k>=2) return 0; else return 1; } int main() { scanf("%d%d",&n,&m); init(); for(int i=1;i<=m;i++) { scanf("%d%d",&e[i].l,&e[i].r); mg(e[i].l,e[i].r); } int k=0; for(int i=1;i<=n;i++) { if(f[i]==i) k++; } if(k>=2) ans=1; for(int i=1;i<=n;i++) { if(ans==1&&i==1) { printf("NO\n"); continue; } init(); scanf("%d",&p[i]); q[p[i-1]]=1; //此农场已关闭 for(int j=1;j<=m;j++) { if(q[e[j].l]==0&&q[e[j].r]==0) mg(e[j].l,e[j].r); } if(check()) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }
9.本题是最长路径,相对于一点到一点的最短路径,优先广度搜索,是一道裸题。
https://www.luogu.com.cn/problem/P1807
#include <bits/stdc++.h> using namespace std; int n,m,edge[5000][5000],f[2000],x,y,z,sum,ans; queue<int>q; void bfs() { memset(f,-1,sizeof(f)); f[1]=0; //f[i]记录到结点i的最长路 q.push(1); //存放到的点 while(!q.empty()) { int cur=q.front(); q.pop(); for(int i=1;i<=n;i++) { if(edge[cur][i]>0&&f[i]<f[cur]+edge[cur][i]) { f[i]=f[cur]+edge[cur][i]; //使用max函数反而会超时,因为程序多次进入if语句,被压入队列中 q.push(i); } } } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); edge[x][y]=max(edge[x][y],z); } bfs(); cout<<f[n]<<endl; return 0; }
10.一个动态迷宫问题。会不断有路障掉下来,本题是输出yes或no,还有一种思路是只考虑路障。
https://www.luogu.com.cn/problem/P3395
#include <bits/stdc++.h> using namespace std; struct node { int x,y,t; }; int mp[1005][1005],zx[2005],zy[2005],fg,n,ans; int dx[4]={0,0,1,-1}; int dy[4]={1,-1,0,0}; bool vis[1005][1005]; queue<node>q; void bfs(int x,int y,int t) { node cur,nxt; cur.x=x;cur.y=y;cur.t=t; q.push(cur); while(!q.empty()) { cur=q.front(); q.pop(); int a,b,c;a=cur.x;b=cur.y;c=cur.t; if(a==n&&b==n) { fg=1;break; } mp[zx[c]][zy[c]]=1; for(int i=0;i<4;i++) { int xx=a+dx[i];int yy=b+dy[i]; if(xx>=1&&xx<=n&&yy>=1&&yy<=n&&vis[xx][yy]==0&&mp[xx][yy]==0) { nxt.x=xx;nxt.y=yy;nxt.t=c+1; vis[xx][yy]=1; q.push(nxt); } } } } int main() { int t;scanf("%d",&t); while(t--) { memset(vis,0,sizeof(vis)); memset(mp,0,sizeof(mp)); fg=0; scanf("%d",&n); for(int i=1;i<=2*n-2;i++) scanf("%d%d",&zx[i],&zy[i]); vis[1][1]=1; bfs(1,1,0); if(fg) cout<<"Yes"<<endl; else cout<<"No"<<endl; } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。