AtCoder Beginner Contest 389 A-E

A

题意:

给定一个一位数乘一位数的式子,求其结果

大致思路:

将一个字符和最后一个字符转为int类型相乘。

#include <bits/stdc++.h>

using namespace std;

typedef long long   ll;

void IOS()

{

    ios::sync_with_stdio(0);

    cin.tie(0);

    cout.tie(0);

}

void solve()

{

    string s;

    cin >> s;

    int a = s[0] - '0';

    int b = s[2] - '0';

    cout << a * b;

}

int main()

{

    //IOS();

    int T;

    //cin >> T;

    T = 1;

    while (T--)

    {

        solve();

    }

}

B

题意:

给定X,并且X是某个数的阶乘,求出那个数

大致思路:

暴力枚举并判断是否等于X即可

#include <bits/stdc++.h>

using namespace std;

typedef long long   ll;

void IOS()

{

    ios::sync_with_stdio(0);

    cin.tie(0);

    cout.tie(0);

}

void solve()

{

    ll x;

    cin >> x;

    for (int i = 1; i <= 30; i++)

    {

        ll sum = 1;

        for (ll j = 1; j <= i; j++)

        {

            sum *= j;

        }

        if (sum == x)

        {

            cout << i;

            return;

        }

    }

}

int main()

{

    //IOS();

    int T;

    //cin >> T;

    T = 1;

    while (T--)

    {

        solve();

    }

}

C

题意:

维护一条蛇队列,有添加蛇,删除蛇,询问某条蛇的位置三种操作

大致思路:

用前缀和维护蛇队列,这样能快速求出蛇的位置

#include <bits/stdc++.h>

using namespace std;

typedef long long   ll;

void IOS()

{

    ios::sync_with_stdio(0);

    cin.tie(0);

    cout.tie(0);

}

ll a[300007], b[300007], cnt = 1, k;

void solve()

{

    ll n, x, y;

    cin >> n;

    while (n--)

    {

        cin >> x;

        if (x == 1)

        {

            cin >> y;

            a[cnt] = y;

            b[cnt] = a[cnt] + b[cnt - 1];

            cnt++;

        }

        else if (x == 3)

        {

            cin >> y;

            cout << b[y + k - 1] - b[k] << '\n';

        }

        else k++;

    }

}

int main()

{

    IOS();

    int T;

    //cin >> T;

    T = 1;

    while (T--)

    {

        solve();

    }

}

D

题意:

以其中一个正方形的中心为圆心,画一个半径为 R 的圆,求有多少个正方形完全包含在圆内

大致思路:

以圆心为原点,先算出坐标轴上包含几个正方形,再算出其他四个象限包含几个正方形

#include <bits/stdc++.h>

using namespace std;

typedef long long   ll;

void IOS()

{

    ios::sync_with_stdio(0);

    cin.tie(0);

    cout.tie(0);

}

ll n, m, a[200007];

void solve()

{

    ll r;

    cin >> r;

    ll ans = 4ll * (floor)(r - 0.5);

    for (int i = 1; i < r; i++)

    {

        ll y = (sqrt(r * r - (i + 0.5) * (i + 0.5)) - 0.5);

        ans =ans+ y * 4;

    }

    cout << ans+1;

}

int main()

{

    IOS();

    int T;

    //cin >> T;

    T = 1;

    while (T--)

    {

        solve();

    }

}

E

题意:

有n种商品,m元钱,购买k件第j种商品的价格是k*k*a[j],求最多买几件商品。

大致思路:

先考虑暴力的思路:一直挑最便宜的买,买到最后一定是件数最多的情况。

观察到还没购买的最便宜的商品的价格随着件数的上升而上升。图像大致如下:

(ab段是由于可能出现多个价格相同的商品)

因为可以通过下一件商品的最低价格(或者是已购买商品的最高价格)求出需要花费的总价,来判断该件数y是否合法。

所以可以对已购买商品的最高价格进行二分,更快求出答案。

同时因为答案可能出现在ab段之间的位置,而二分也无法到达该位置,可以在mid指针指向b-1(ab对于x轴的坐标 - 1)时,用剩下的钱尽可能地去购买等于(mid+1)价格的产品去到达ab之间的位置。(看了暴力代码就非常好理解了)

暴力代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long   ll;

void IOS()

{

    ios::sync_with_stdio(0);

    cin.tie(0);

    cout.tie(0);

}

ll n, m, a[200007], as, ans, flag[200007];

priority_queue<pair<ll, ll>, vector<pair<ll, ll>>, greater<pair<ll, ll>>>q;

ll ff(ll x)

{

    ll y = x - 1;

    return x * x - y * y;

}

void solve()

{

    cin >> n >> m;

    for (int i = 1; i <= n; i++)

    {

        cin >> a[i];

        q.emplace(a[i],i);

    }

    while (!q.empty())

    {

        ll t1 = q.top().first;

        ll t2 = q.top().second;

        q.pop();

        if (t1 > m)break;

        ans++;

        flag[t2]++;

        m -= t1;

        ll k = flag[t2]+1;

        k = ff(k);

        q.emplace(k * a[t2], t2);

    }

    cout << ans << '\n';

}

int main()

{

    IOS();

    int T;

    //cin >> T;

    T = 1;

    while (T--)

    {

        solve();

    }

}

正解:

#include <bits/stdc++.h>

using namespace std;

typedef long long   ll;

#define int __int128

void IOS()

{

    ios::sync_with_stdio(0);

    cin.tie(0);

    cout.tie(0);

}

ll n, m, a[200007], as, ans, d[200007];

bool check(int mid)

{

    int sum = 0;

    as = 0;

    for (int i = 1; i <= n; i++)

    {

        int k = mid / a[i] + 1 >> 1;

        sum += k * k * a[i];

        if (sum > m)return 0;

        as += k;

        d[i] = k;

    }

    for (int i = 1; i <= n; i++)

    {

        int tmp = ((d[i] + 1) * (d[i] + 1) - d[i] * d[i]) * a[i];

        if (tmp != mid + 1||tmp+sum>m)continue;

        sum += tmp;

        as++;

    }

    return 1;

}

void solve()

{

    cin >> n >> m;

    for (int i = 1; i <= n; i++)cin >> a[i];

    sort(a + 1, a + 1 + n);

    int l = 0, r = m;

    while (l < r)

    {

        int mid = l + r + 1 >> 1;

        if (check(mid))

        {

            l = mid;

        }

        else

        {

            r = mid - 1;

        }

        ans = max(as, ans);

    }

   cout << ans;

}

signed main()

{

    IOS();

    int T;

    //cin >> T;

    T = 1;

    while (T--)

    {

        solve();

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值