P1135 奇怪的电梯
1.与视频里的bfs例题一样,每一次分为上楼与下楼两个选择,判断后入队
2.用vis[i]标记到过的楼层优化
#include <bits/stdc++.h>
using namespace std;
int n,start,end;
int a[205],vis[202];
struct pos{
int level; //目前的楼层
int step; //第几步
};
void bfs();
int main(){
while(scanf("%d",&n)==1){
if (n==0) break;
scanf("%d%d",&start,&end);
for (int i=1;i<=n;i++){
scanf("%d",&a[i]);
vis[i]=0;
}
bfs();
}
return 0;
}
void bfs(){
pos cur,nex;
cur.level=start;
cur.step=0;
queue<pos>qu;
qu.push(cur);
vis[start]=1;
while (!qu.empty()){
cur=qu.front();
qu.pop();
if (cur.level==end){
cout<<cur.step;
return;
}
nex.level=cur.level+a[cur.level];
nex.step=cur.step+1;
if (nex.level<=n){
if(vis[nex.level]==0){
vis[nex.level]=1;
qu.push(nex);
}
}
nex.level=cur.level-a[cur.level];
nex.step=cur.step+1;
if (nex.level>=1){
if(vis[nex.level]==0){
vis[nex.level]=1;
qu.push(nex);
}
}
}
cout<<"-1"<<endl;
return;
}
P1443 马的遍历
1.每一次马都有八个跳法,先造两个dx与dy数组记录
2.用f[i][j]记录该位置的步数
#include <bits/stdc++.h>
using namespace std;
int f[450][450],vis[450][450];
struct pos{
int a;
int b;
};
int main(){
int dx[8]={-1,-2,-2,-1,1,2,2,1};
int dy[8]={2,1,-1,-2,2,1,-1,-2};
int n,m,x,y;
cin>>n>>m>>x>>y;
pos cur,nex;
cur.a=x; cur.b=y;
queue<pos> q;
memset(f,-1,sizeof(f));
memset(vis,0,sizeof(vis));
f[x][y]=0;vis[x][y]=1;
q.push(cur);
while (!q.empty()){
int xx=q.front().a,yy=q.front().b;
q.pop();
for (int i=0;i<8;i++){
nex.a=xx+dx[i],nex.b=yy+dy[i];
if (nex.a<1 ||nex.a>n||nex.b<1||nex.b>m||vis[nex.a][nex.b]) { //跑出棋盘或者重复到同一位置都直接跳过这个循环
continue;
}else{
vis[nex.a][nex.b]=1;
q.push(nex);
f[nex.a][nex.b]=f[xx][yy]+1;
}
}
}
for (int i=1;i<=n;i++){
for (int j=1;j<=m;j++){
printf("%-5d",f[i][j]);
}
cout<<endl;
}
return 0;
}
P3958 [NOIP2017 提高组] 奶酪
1.用到并查集的算法
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int f[1010];
int find(int x){
if (f[x]!=x) return f[x]=find(f[x]);
return f[x];
} //查找
ll dis(ll x,ll y,ll z,ll x1,ll y1,ll z1){
return (x-x1)*(x-x1)+(y-y1)*(y-y1)+(z-z1)*(z-z1);
}
ll x[100010],y[100010],z[10010];
int f1[100010],f2[100010];
int main(){
int t,n;
ll r,h;
cin>>t;
for (int i=1;i<=t;i++){
cin>>n>>h>>r;
int cnt1=0,cnt2=0;
for (int j=1;j<=n;j++){
f[j]=j; //初始化
}
for (int j=1;j<=n;j++){
cin>>x[j]>>y[j]>>z[j];
if (z[j]+r>=h){ //与顶部相交的奶酪
cnt1+=1;
f1[cnt1]=j;
}
if (z[j]-r<=0){ //与底部相交的奶酪
cnt2+=1;
f2[cnt2]=j;
}
for (int k=1;k<j;k++){
if (dis(x[j],y[j],z[j],x[k],y[k],z[k])<=4*r*r){
int a1=find(j);
int a2=find(k);
if (a1!=a2) f[a1]=a2; //两圆相切或相交并入同一集合
}
}
}
int cn=0;
for (int j=1;j<=cnt1;j++){
for (int k=1;k<=cnt2;k++){
if (find(f1[j])==find(f2[k])){ //若与底部和顶部都相交的圆都在同一集合,则相连
cn=1;
break;
}
}
if (cn==1) break;
}
if (cn==1) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
P1162 填涂颜色
#include <bits/stdc++.h>
using namespace std;
int a[40][40],b[40][40];
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
int n,i,j;
void dfs(int p,int q){
if (p<0||p>n+1||q<0||q>n+1||a[p][q]!=0) return;
a[p][q]=1;
for (int i=0;i<4;i++){
dfs(p+dx[i],q+dy[i]);
}
}
int main(){
cin>>n;
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++){
cin>>b[i][j];
if (b[i][j]==0) a[i][j]=0;
else a[i][j]=2;
}
}
dfs(0,0);
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++){
if (a[i][j]==0){
cout<<2<<" ";
}else{
cout<<b[i][j]<<" ";
}
}
cout<<endl;
}
return 0;
}