#617Div.3

C.Yet Another Walking Robot

map的应用

大意: 一个机器人(0,0)点可以进行上(U,y+1)、下(D,y-1)、左(L,x+1)、右(R,x-1)的操作,给你系列操作符(UDLR)让你简化(删除)他的操作指令,达到的终点都是同一位置。只能简化一个区间的。如果不能删除,输出-1,否则输出删除的左端点l和右端点r,使r-l+1应该尽可能小,若有多个相同的答案,输出一个就行。

题解: 用stl::map开一个数组vis,标记走过的点,进行判断,如果这个点在原来被标记过,并且使得r-l+1小,则来跟新vis[]和左端点l右端点r。

ac代码:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    int t, n;
    string s;
    cin >> t;
    while (t--)
    {
        cin >> n >> s;
        int l = -1, r = n;
        map<pair<int, int>, int> vis;
        pair<int, int> zb = {0, 0};
        vis[zb] = 0;                //vis[]代表起始端
        for (int i = 0; i < n; i++) //i代表尾端
        {
            if (s[i] == 'L')
                ++zb.first;
            if (s[i] == 'R')
                --zb.first;
            if (s[i] == 'U')
                ++zb.second;
            if (s[i] == 'D')
                --zb.second;
            if (vis.count(zb)) //在map中,若能找到就输出1,否则为0
            {
                if (i - vis[zb] < r - l)
                {
                    r = i;
                    l = vis[zb];
                }
            }
            vis[zb] = i + 1; //储存当前坐标的起始位置
        }
        if (l == -1)
            cout << -1 << endl;
        else
            cout << l+1 << " " << r+1 << endl;
    }

    return 0;
}

D. Fight with Monsters

贪心

大意: 我和对手去杀n个怪物,我每杀死一个怪物就能获得1金币。我的攻击力是a,对手的攻击力是b,每个怪物的血量是i-hp。我先手攻击,但是我能使用k次秘术,能使对手放弃一次攻击怪物的机会。输出我最多能获得多少金币。

题解: 1我们可以设tmp=a+b,并对hp%tmp;2若tmp=0,我们可以往前倒回一个回合,此时怪物hp=tmp,这时我们再使用秘术,计算使用t次秘术,并存入数组num[]中,t=[tmp/a]-1,([tmp/a]的意思是向上取整)。3 若tmp!=0,当前hp=hp%tmp,t=[tmp/a]-1,并存放到数组中。4对num[]数组进行排序,计算能再k次能的最大击杀数。

ac代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
    ios::sync_with_stdio(false);
    int n, a, b, k, hp, ans = 0;
    vector<int> num;
    ll tmp;
    cin >> n >> a >> b >> k;
    tmp = a + b;
    while (n--)
    {
        cin >> hp;
        hp %= tmp;
        if (!hp)
            hp = tmp;
        int t = ceil(hp * 1.0 / a) - 1;
        num.push_back(t);
    }
    sort(num.begin(), num.end());
    for (vector<int>::iterator iter = num.begin(); iter != num.end(); ++iter)
    {
        if (k >= *iter)
        {
            ans++;
            k -= *iter;
        }
        else
            break;
    }
    cout << ans << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值