AtCoder Beginner Contest 246(A-E)

目录

A - Four Points

B - Get Closer

C - Coupon

D - 2-variable Function

E - Bishop 2


A - Four Points

签到,给出和xy轴平行的矩形的三个点,求第四个点

#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<vector>
#include<cstring>
#include<string>
using namespace std;
int main()
{
    int x1,x2,x3,y1,y2,y3;
    cin>>x1>>y1>>x2>>y2>>x3>>y3;
    if(x1==x2)
        cout<<x3<<" ";
    else if(x3==x2)
        cout<<x1<<" ";
    else if(x1==x3)
        cout<<x2<<" ";
    if(y1==y2)
        cout<<y3<<" ";
    else if(y3==y2)
        cout<<y1<<" ";
    else if(y1==y3)
        cout<<y2<<" ";
    return 0;
}

B - Get Closer

签到,给出一个点,以这个点为方向,求从(0,0)前进1个单位长度后的位置坐标

#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<vector>
#include<cstring>
#include<string>
using namespace std;
int main()
{
    double a,b,c=1;
    cin>>a>>b;
    if(a==0)
        printf("0 1");
    else if(b==0)
        printf("1 0");
    else
    {
        double x,y,ans;
        ans=sqrt((a*a)+(b*b));
        x=a/ans;
        y=b/ans;
        printf("%.8lf %.8lf",x,y);
    }
    return 0;
}

C - Coupon

有n个商品,你有k张打折券,每张券可以减免x元,当商品减免x元后为负数时直接为0元.

模拟,首先遍历商品数组,在不把商品减免为0的情况下尽量进行减免.然后再把剩下的商品从大到小排序,再从头开始遍历,将前面的商品化为免费,知道券用完即可.

#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<vector>
#include<cstring>
#include<string>
#define int long long
using namespace std;
int arr[200005];
bool cmp(int a,int b)
{
    return a>b;
}
signed main()
{
    int n,k,x;
    scanf("%lld%lld%lld",&n,&k,&x);
    for(int i=0;i<n;i++)
        scanf("%lld",&arr[i]);
    for(int i=0;i<n;i++)
    {
        if(k==0)
            break;
        if(k>arr[i]/x)
        {
            k-=(arr[i]/x);
            arr[i]-=(arr[i]/x)*x;
        }
        else
        {
            arr[i]-=k*x;
            k=0;
            continue;
        }
    }
    sort(arr,arr+n,cmp);
    int ans=0;
    for(int i=0;i<n;i++)
    {
        if(arr[i]==0)
            break;
        if(k!=0)
        {
            k--;
            continue;
        }
        ans+=arr[i];
    }
    printf("%lld",ans);
    return 0;
}

D - 2-variable Function

给你一个数字n,求一个大于它且满足f(a,b)=a^3+a^2b+ab^2+b^3(a,b为非负数)的数的最小值.

双指针做法,分别从1和1e6两个指针进行操作,当两者进行f(l,r)运算时,大于n时就让右端点向左移动,小于n则左端点向右移动,这样可以筛去很多不合要求的情况.在剩余情况中取最小值即可.

#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<vector>
#include<cstring>
#include<string>
#define int long long
using namespace std;
int n;
signed main()
{
    int ans=1e18+1;
    scanf("%lld",&n);
    int r=1000000;
    for(int l=0;l<=1000000;l++)
    {
        int temp=l*l*l+r*r*r+r*r*l+l*l*r;
        while(temp>=n&&r>=0)
        {
            ans=min(ans,temp);
            r--;
            temp=l*l*l+r*r*r+r*r*l+l*l*r;
        }
    }
    printf("%lld",ans);
    return 0;
}

E - Bishop 2

搜索+剪枝

有一个棋盘,'.'可以走,'#'不可以走也不可以越过,棋子只能向左上左下右上右下四个方向移动(不论移动多长都算一步),问最少步数.

该题在基础的bfs基础上多加一个标记,vis[x][y][to],to是四个方向的状态,我们只需要标记每个点从四个方向的状态即可.要注意的是剪枝时,当一个点不能往前走或者已经从这个点的方向走过了,需要直接break.

#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<vector>
#include<cstring>
#include<string>
using namespace std;
int n,sx,sy,ex,ey;
int dx[4]={1,1,-1,-1};
int dy[4]={1,-1,1,-1};
int vis[1505][1505][4];
char ma[1505][1505];
struct node
{
    int x,y,step;
};
void bfs()
{
    queue<node>qu;
    node bef;
    bef={sx,sy,0};
    qu.push(bef);
    while(qu.size())
    {
        bef=qu.front();
        qu.pop();
        if(bef.x==ex&&bef.y==ey)
        {
            printf("%d\n",bef.step);
            return;
        }
        for(int i=0;i<4;i++)
        {
            for(int j=1;;j++)
            {
                int xx=bef.x+j*dx[i],yy=bef.y+j*dy[i];
                if(xx<1||xx>n||yy<1||yy>n)
                    break;
                if(ma[xx][yy]=='#')
                    break;
                if(vis[xx][yy][i]==1)
                    break;
                vis[xx][yy][i]=1;
                qu.push({xx,yy,bef.step+1});
            }
            for(int j=1;;j++)
            {
                int xx=bef.x+j*dx[i],yy=bef.y+j*dy[i];
                if(xx<1||xx>n||yy<1||yy>n)
                    break;
                if(ma[xx][yy]=='#')
                    break;
                if(vis[xx][yy][i]==1)
                    break;
                vis[xx][yy][i]=1;
                qu.push({xx,yy,bef.step+1});
            }
            for(int j=1;;j++)
            {
                int xx=bef.x+j*dx[i],yy=bef.y+j*dy[i];
                if(xx<1||xx>n||yy<1||yy>n)
                    break;
                if(ma[xx][yy]=='#')
                    break;
                if(vis[xx][yy][i]==1)
                    break;
                vis[xx][yy][i]=1;
                qu.push({xx,yy,bef.step+1});
            }
            for(int j=1;;j++)            
            {
                int xx=bef.x+j*dx[i],yy=bef.y+j*dy[i];
                if(xx<1||xx>n||yy<1||yy>n)
                    break;
                if(ma[xx][yy]=='#')
                    break;
                if(vis[xx][yy][i]==1)
                    break;
                vis[xx][yy][i]=1;
                qu.push({xx,yy,bef.step+1});
            }
        }
    }   
    printf("-1");
}
int main()
{
    scanf("%d",&n);
    scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
    for(int i=1;i<=n;i++)
        scanf("%s",ma[i]+1);
    bfs();
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值