牛客练习赛12

A-圆圆

链接:https://www.nowcoder.net/acm/contest/68/A

题目描述

我们定义一个圆 C 为以原点 (0, 0) 为中心的单位圆(半径为 1 的圆)。给定在 C 圆周上相异的两点

A, B。请问由 A 出发,沿着圆周走到 B,是顺时针走比较近,还是逆时针走比较近呢?

C 的圆周上的所有点都可以用 (cos(t), sin(t)) 来表示,其中 t 的物理意义为角度。也就是说,在圆 C 中,给定一角度 t 即可确定在圆周上的一点。在这题中,所有的角度皆以弧度制表示,另外,由于不同的t 值有机会对应到同一个圆周上的点,我们限制t 的范围为[-π,π )。

本题中,我们会用tA 以及tB 来代表点A 及点B,数学上,A = (cos(tA), sin(tA)), B = (cos( tB), sin(tB))。

输入描述:

 
 

输入的第一行有一个正整数T,代表接下来共有几组测试数据。

接下来的T行,每行有两个浮点数tA, tB,代表一组数据。

输出描述:

对于每组数据请输出一行,如顺时针比较近请输出“clockwise”,否则请输出“counterclockwise”。

思路:先将角度A和B化为[0,2π],用角度衡量弧度,顺时针距离为l,逆时针距离为r,如果a>b则l=a-b,r=2π -l,如果b>a,则r=b-a,l=2π-r;

代码如下:

#include<bits/stdc++.h>
using namespace std;
#define pi 3.14159
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        double a,b,l,r;
        cin>>a>>b;
        if(a<0)
            a=2*pi+a;
        if(b<0)
            b=2*pi+b;
        if(a>=b)
        {
            l=a-b;
            r=2*pi-l;
        }
        else
        {
            r=b-a;
            l=2*pi-r;
        }
        if(l<=r)
            cout<<"clockwise\n";
        else
            cout<<"counterclockwise\n";
    }
    return 0;
}

B-迷宫

链接: https://www.nowcoder.net/acm/contest/68/B

题目描述

这是一个关于二维迷宫的题目。我们要从迷宫的起点 'S' 走到终点 'E',每一步我们只能选择上下左右四个方向中的一个前进一格。 'W' 代表墙壁,是不能进入的位置,除了墙壁以外的地方都可以走。迷宫内的 'D' 代表一道上锁的门,只有在持有钥匙的时候才能进入。而 'K' 则代表了钥匙,只要进入这一格,就会自动地拿到钥匙。最后 '.' 则是代表空无一物的地方,欢迎自在的游荡。

本题的迷宫中,起点、终点、门跟钥匙这四个特殊物件,每一个恰好会出现一次。而且,此迷宫的四周 (最上面的一行、最下面的一行、最左边的一列以及最右边的一列) 都会是墙壁。

请问,从起点到终点,最少要走几步呢?

输入描述:

输入的第一行有两个正整数H, W,分别代表迷宫的长跟宽。
接下来的H行代表迷宫,每行有一个长度恰为W的字串,此字串只包含`'S'`, `'E'`, `'W'`, `'D '`, `'K'`, `'.'`这几种字元。

输出描述:

请在一行中输出一个整数代表答案,如果无法从起点走到终点,请输出-1。

思路:bfs搜索,注意取到钥匙后可以往回走,用flag标记是否取到钥匙,vis1标记总的走过的点,vis2标记取到钥匙后走过的点

代码如下:

#include<bits/stdc++.h>
using namespace std;
char z[510][510];
int n,m,a,b,c,d,dx[4]={-1,1,0,0},dy[4]={0,0,-1,1},flag,vis1[510][510],vis2[510][510];
struct pp
{
    int x,y,s,flag;//flag记录是否取到钥匙,如果为1则取到钥匙,为0则没取到
};
bool operator<(const pp&a,const pp&b)
{
    return a.s>b.s;
}
priority_queue<pp>q;
void bfs()
{
   pp p;
   p.x=a;
   p.y=b;
   p.s=0;
   p.flag=0;
   q.push(p);
   while(!q.empty())
   {
       p=q.top();q.pop();
       for(int i=0;i<4;i++)
       {
           pp l;
           l.x=p.x+dx[i];l.y=p.y+dy[i];l.s=p.s+1;l.flag=p.flag;
           if(z[l.x][l.y]!='W'&&(!vis1[l.x][l.y]||(!vis2[l.x][l.y]&&l.flag)))
           {
               if(l.x==c&&l.y==d)
               {
                   cout<<l.s<<endl;
                   flag=0;
                   return ;
               }
               if(z[l.x][l.y]=='.'||z[l.x][l.y]=='S')
                   q.push(l);
               else if(z[l.x][l.y]=='K')
               {
                   l.flag=1;
                   q.push(l);
               }
               else if(z[l.x][l.y]=='D'&&l.flag)
               q.push(l);
               vis1[l.x][l.y]=1;
               if(l.flag)
               vis2[l.x][l.y]=1;
           }
       }
   }
}
int main()
{
    while(cin>>n>>m)
    {
        flag=1;
        memset(vis1,0,sizeof(vis1));
        memset(vis2,0,sizeof(vis2));
        while(!q.empty())
            q.pop();
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
            {
                cin>>z[i][j];
                if(z[i][j]=='S')
                {
                    a=i;
                    b=j;
                }
                if(z[i][j]=='E')
                {
                    c=i;
                    d=j;
                }
            }
        bfs();
        if(flag)
            cout<<"-1\n";
    }
    return 0;
}

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值