第六周必做题/选做题
1. 奇怪的电梯
板子,分上下层就可。
#include<bits/stdc++.h>
using namespace std;
int n,begn,End;
struct pos {
int flor;
int step;
};
int k[210]= {0};
int vis[210]= {0};
void bfs();
int main()
{
scanf("%d",&n);
scanf("%d%d",&begn,&End);
for(int i=1; i<=n; i++)
{
scanf("%d",&k[i]);
vis[i]=0;
}
bfs();
return 0;
}
void bfs()
{
pos cur,nex;
queue<pos>pu;
cur.flor=begn;
cur.step=0;
pu.push(cur);
vis[begn]=1;
while(!pu.empty())
{
cur=pu.front();
pu.pop();
if(cur.flor==End)
{
printf("%d",cur.step);
return;
}
nex.flor=cur.flor-k[cur.flor];
nex.step=cur.step+1;
if(nex.flor>0&&!vis[nex.flor])
{
pu.push(nex);
vis[nex.flor]=1;
}
nex.flor=cur.flor+k[cur.flor];
nex.step=cur.step+1;
if(nex.flor<=n&&!vis[nex.flor])
{
pu.push(nex);
vis[nex.flor]=1;
}
}
printf("-1");
return;
}
2. 马的遍历
跟电梯差不多,就是有八个分支,循环一下子。
#include<bits/stdc++.h>
using namespace std;
int n,m;
int xx,yy;
int vis[410][410];
int mapp[410][410];
void bfs();
void print();
struct PIO
{
int x;
int y;
int step;
};
bool pd(PIO a)
{
if(1<=a.x&&a.x<=n&&1<=a.y&&a.y<=m)return 1;
return 0;
}
int mx[9]= {0,2,2,1,-1,-2,-2,-1,1};
int my[9]= {0,1,-1,-2,-2,-1,1,2,2};
int main()
{
memset(vis,0,sizeof(vis));
memset(mapp,-1,sizeof(mapp));
scanf("%d%d%d%d",&n,&m,&xx,&yy);
bfs();
print();
return 0;
}
void bfs()
{
PIO cur,nex;
cur.x=xx;
cur.y=yy;
cur.step=0;
queue<PIO>qu;
qu.push(cur);
vis[cur.x][cur.y]=1;
mapp[cur.x][cur.y]=cur.step;
while(!qu.empty())
{
cur=qu.front();
qu.pop();
for(int i=1; i<=8; i++)
{
nex.x=cur.x+mx[i];
nex.y=cur.y+my[i];
if(pd(nex)&&!vis[nex.x][nex.y])
{
nex.step=cur.step+1;
qu.push(nex);
vis[nex.x][nex.y]=1;
mapp[nex.x][nex.y]=nex.step;
}
}
}
}
void print()
{
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
printf("%-4d",mapp[i][j]);
}
cout<<endl;
}
}
3. [NOIP2017 提高组] 奶酪
这个不是AC。
#include<bits/stdc++.h>
using namespace std;
long long int t,n,h,r;
int vis[1010];
struct PIO
{
int in=0;
double x;
double y;
double z;
int out=0;
};
void bfs(PIO pio[]);
double poww(double x)
{
return x*x;
}
bool pd(PIO a,PIO b)
{
double len=poww(a.x-b.x)+poww(a.y-b.y)+poww(a.z-b.z);
if(len<=4*r*r)return 1;
return 0;
}//判断是否可以联通
int main()
{
scanf("%d",&t);
while(t)
{
memset(vis,0,sizeof(vis));
scanf("%d%d%d",&n,&h,&r);
PIO pio[n+100];
for(int i=1;i<=n;i++)
{
scanf("%lf%lf%lf",&pio[i].x,&pio[i].y,&pio[i].z);
if(pio[i].z<=r&&-r<=pio[i].z)
{
pio[i].in=1;
//cout<<i<<"可以进去"<<endl;
}
if(h-r<=pio[i].z&&pio[i].z<=h+r)
{
pio[i].out=1;
//cout<<i<<"可以出去"<<endl;
}
}
/*输入坐标,并按序号标记,判断是否可以进入
或者离开*/
bfs(pio);
t--;
}
return 0;
}
void bfs( PIO pio[])
{
for(int i=1;i<=n;i++)
{
if(pio[i].in)
{
queue<PIO>qu;
PIO cur,nex;
cur=pio[i];
vis[i]=1;//标记已经走的
qu.push(cur);
if(cur.out)
{
cout<<"Yes"<<endl;
return;
}
while(!qu.empty())
{
cur=qu.front();
qu.pop();
if(cur.out)
{
cout<<"Yes"<<endl;
return;
}
for(int j=1;j<=n;j++)
{
if(j!=i&&pd(pio[i],pio[j])&&!vis[j])
{
nex=pio[j];
vis[j]=1;
qu.push(nex);
}
}
}
}
}
cout<<"No"<<endl;
return;
}
***卧槽卧槽卧槽!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!我跑出来啦啊啊啊啊啊啊 ***
上面那个是个30还是40分的,我本来准备混,但写下面这个时才周四,我寻思再改改吧,然后我就哎呀我去我太他妈牛逼了。下面是哥的show time:
pio是所有圆心的结构体数组,然后有一个in和out,是看这个⚪能不能进入或出去,能的话相应变成1(嘎嘎有用噢);
忽略8888888.。。。。。。
主角coming!!!
因为这个题只看能不能出去,所以能出去直接yes结束就欧卡。
一开始我是边判断进入点边放入队列,就是一个进入点后面跟所有能和他联通的,不过这个只能过4个测试点。
然后我就改了下面这个:首先先把所有进入点放入队列,然后开始bfs,it is easy!
#include<bits/stdc++.h>
using namespace std;
#define ll long long
long long int t,n,h,r;
int vis[1010];
struct PIO
{
int in=0;
ll x;
ll y;
ll z;
int out=0;
};
void bfs(PIO pio[]);
ll poww(ll x)
{
if(x<0)x=-x;
return x*x;
}
ll LEN(PIO a,PIO b)
{
return poww(a.x-b.x)+poww(a.y-b.y)+poww(a.z-b.z);
}
bool pd(PIO a,PIO b)
{
ll len=LEN(a,b);
if(len<=4*r*r)return 1;
return 0;
}//判断是否可以联通
int main()
{
scanf("%d",&t);
while(t)
{
memset(vis,0,sizeof(vis));
scanf("%lld%lld%lld",&n,&h,&r);
PIO pio[n+100];
for(int i=1;i<=n;i++)
{
scanf("%lld%lld%lld",&pio[i].x,&pio[i].y,&pio[i].z);
if(pio[i].z<=r&&-r<=pio[i].z)
{
pio[i].in=1;
///cout<<i<<"88888888888888888可以进去"<<endl;
}
if(h-r<=pio[i].z&&pio[i].z<=h+r)
{
pio[i].out=1;
//cout<<i<<"777777777777777777可以出去"<<endl;
}
}
/*输入坐标,并按序号标记,判断是否可以进入
或者离开*/
bfs(pio);
t--;
}
return 0;
}
void bfs( PIO pio[])
{
queue<PIO>qu;
for(int i=1;i<=n;i++)
{
if(pio[i].in==1)qu.push(pio[i]);
}
PIO cur,nex;
while(!qu.empty())
{
cur=qu.front();
qu.pop();
if(cur.out==1)
{
cout<<"Yes"<<endl;
return;
}
for(int i=1;i<=n;i++)
{
if(LEN(cur,pio[i])!=0&&pd(cur,pio[i])&&!vis[i])
{
nex=pio[i];
vis[i]=1;
qu.push(nex);
}
}
}
cout<<"No"<<endl;
return;
}
4. 填涂颜色
这个我耍滑了一下,就是当第一个1出现时,它右下角咋的也得是个圈内的0,找到这个0然后直接欧克
#include<bits/stdc++.h>
using namespace std;
int n;
struct PIO
{
int x,y;
};
int a[40][40];
int vis[40][40];
int mx[5]={0,1,0,-1,0};
int my[5]={0,0,1,0,-1};
void bfs()
{
PIO cur,nex;
int falg=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i][j]==2)
{
cur.x=i;
cur.y=j;
vis[i][j]=1;
falg=1;
break;
}
}
if(falg==1)break;
}
queue<PIO>qu;
qu.push(cur);
while(!qu.empty())
{
cur=qu.front();
qu.pop();
//cout<<cur.x<<cur.y<<endl;
for(int i=1;i<=4;i++)
{
nex.x=cur.x+mx[i];
nex.y=cur.y+my[i];
if(!vis[nex.x][nex.y])
{
qu.push(nex);
vis[nex.x][nex.y]=1;
a[nex.x][nex.y]=2;
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}
int main()
{
memset(vis,0,sizeof(vis));
memset(a,0,sizeof(a));
cin>>n;
int num=1;
int fx,fy;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>a[i][j];
if(a[i][j]==1)vis[i][j]=1;
while(num)
{
if(a[i][j]==1)
{
fx=i+1;
fy=j+1;
vis[fx][fy]=1;
num--;
}
else break;
}
}
}
a[fx][fy]=2;
bfs();
return 0;
}