AtCoder Beginner Contest 364 A~E

本期封面原图 画师Namie

A - Glutton Takahashi

题意

给了N碟菜 有的太咸有的太甜 太咸无所谓 但是过甜的吃两碗就会齁到立即停止就餐 问能不能吃完所有菜

思路

按照题意模拟即可 这题要是没有样例二至少我会WA一发 吃到最后一盘才齁到需要特判

代码

#include <bits/stdc++.h>
#define mod 998244353
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

int main()
{
    int n;
    scanf("%d",&n);
    string lst;
    cin >> lst;
    int flag=1;
    for(int i=1;i<n;i++)
    {
        string s;
        cin>>s;
        if(s=="sweet" and lst=="sweet")
        {
            if(i!=n-1)
            {
                flag = 0;
            }
        }
        lst=s;
    }
    if(flag==1) cout << "Yes" << endl;
    else cout << "No" << endl;
    return 0;
}

B - Grid Walk

题意

给了一个迷宫和一串指令 给定初始位置 指令表示上下左右往哪里走 走不动就不动 问最终到的位置的坐标

思路

依据题意模拟即可

代码

#include <bits/stdc++.h>
#define mod 998244353
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

int main()
{
    int H,W;
    cin >> H >> W;
    pii now;
    cin >> now.first >> now.second;
    string mp[H+1];
    for (int i = 1; i <= H; i++)
    {
        cin >> mp[i];
        mp[i] = " "+mp[i];
    }
    string cmd;
    cin >> cmd;
    for(char c:cmd)
    {
        if(c=='U' and now.first>1 and mp[now.first-1][now.second]=='.') now.first--;
        if(c=='D' and now.first<H and mp[now.first+1][now.second]=='.') now.first++;
        if(c=='L' and now.second>1 and mp[now.first][now.second-1]=='.') now.second--;
        if(c=='R' and now.second<W and mp[now.first][now.second+1]=='.') now.second++;
    }
    cout << now.first << " " << now.second << endl;
    return 0;
}

C - Minimum Glutton

题意

又是n碟菜 每碟菜的甜度和咸度给定 总甜度或者咸度超过阈值就吃不了了 问最少吃多少碟

思路

最少只需要爆一个条即可 所以不用管另外一个数值 就是吃最咸的和吃最甜的取一个min值就可以了

代码

#include <bits/stdc++.h>
#define mod 998244353
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
struct node{
    ll a,b;
};
bool cmp1(node x,node y)
{
    return x.a>y.a;
}
bool cmp2(node x,node y)
{
    return x.b>y.b;
}

int main()
{
    ll n,x,y;
    cin >> n >> x >> y;
    node all[n+1];
    for(ll i=1;i<=n;i++) cin>>all[i].a;
    for(ll i=1;i<=n;i++) cin>>all[i].b;
    sort(all+1,all+n+1,cmp1);
    ll i;
    for(i=1;i<=n and x>=0;i++)
    {
        x-=all[i].a;
    }
    ll ans=i-1;
//    cout<<ans<<endl;
    sort(all+1,all+n+1,cmp2);
    for(i=1;i<=n and y>=0;i++)
    {
        y-=all[i].b;
    }
//    cout<<i-1<<endl;
    ans=min(ans,i-1);
    cout << ans;
    return 0;
}

D - K-th Nearest

题意

给定数轴上的n个点 然后查询q次 每次查询距离坐标b第k近的点到坐标b的距离

思路

提到按顺序第几个肯定就是二分啦!这题比较复杂的就是有一个二分套二分,我们外面二分答案,对于每个k,肯定是在a数组里面取lower_bound和up_bound取差值看是不是他,是的话就说明可以

代码

#include <bits/stdc++.h>
#define mod 998244353
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const int N=1e5+5;
int n,q;
vector<int> a(N);
bool check(int mid,int k,int b)
{
    int l=lower_bound(a.begin()+1,a.begin()+n+1,b-mid)-a.begin();
    int r=upper_bound(a.begin()+1,a.begin()+n+1,b+mid)-a.begin();
    return r-l>=k;
}

int main()
{
    scanf("%d%d",&n,&q);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d",&a[i]);
    }
    sort(a.begin()+1,a.begin()+n+1);
    while(q--)
    {
        int b,k;
        scanf("%d%d",&b,&k);
        int l=-10,r=1e9+10;
        while(r-l>1)
        {
            int mid=(l+r)/2;
            if(check(mid,k,b)) r=mid;
            else l=mid;
        }
        printf("%d\n",r);
    }
    return 0;
}

E - Maximum Glutton

题意

还是n碟菜 每碟菜的甜度和咸度给定 总甜度或者咸度超过阈值就吃不了了 问最多吃多少碟

思路

一个很明显的二维背包,但是如果直接二维背包好像又不太对,因为x和y的范围太大了。但是我们又发现n特别小,所以我们可以使用交换键值法 d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k]表示前i道菜吃了j道,总甜度值为k时的咸度值。维护的过程中我们尽量保持咸度值最小即可

代码

#include <bits/stdc++.h>
#define mod 998244353
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

int main()
{
    int n,x,y;
    cin >> n >> x >> y;
    vector<int> a(n),b(n);
    for (int i = 0; i < n; i++) cin >> a[i] >> b[i];
    vector dp(n + 1, vector(n + 1, vector<int>(x + 1, 1e9)));
    dp[0][0][0] = 0;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<=i;j++)
        {
            for(int k=0;k<=x;k++)
            {
                dp[i+1][j][k] = min(dp[i+1][j][k],dp[i][j][k]);
                if(k+a[i]<=x)
                {
                    dp[i+1][j+1][k+a[i]]= min(dp[i+1][j+1][k+a[i]],dp[i][j][k]+b[i]);
                }
            }
        }
    }
    for (int i = n; i >= 0; i--)
    {
        for (int j = 0; j <= x; j++)
        {
            if (dp[n][i][j] <= y)
            {
                printf("%d\n", min(i+1,n));
                return 0;
            }
        }
    }
    return 0;
}
  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值