第六周必做题/选做题

第六周必做题/选做题

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值