华东师范大学 2017 计算机系暑期夏令营机考

华东师范大学 2017 计算机系暑期夏令营机考

传送门:https://acm.ecnu.edu.cn/problem/list/?source=2017 计算机系暑期夏令营机考

中文题不写题面了

我不知道我第一次打开界面为啥题号是倒着的,于是先看了“送分题”,然后按序号开的题,我竟反而觉得送分题真的送分题

有两题还没做,先放放

3307. 送分题

idea:

挺裸的莫队

直接抄的y总板子改了改

甚至觉得这题比后面的简单

code:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>

using namespace std;

typedef long long LL;
const int N = 500010;

int n, m, len;
int w[N], cnt[N];
LL ans[N];
struct Query
{
    int id, l, r;
}q[N];
vector<int> nums;

int get(int x)
{
    return x / len;
}

bool cmp(const Query& a, const Query& b)
{
    int i = get(a.l), j = get(b.l);
    if (i != j) return i < j;
    return a.r < b.r;
}

void add(int x, LL& res)
{
    if(cnt[x] == 2) res--;
    cnt[x] ++ ;
    if(cnt[x] == 2) res ++;
//    res = max(res, (LL)cnt[x] * nums[x]);
}

int main()
{
    scanf("%d%d", &n, &m);
    len = sqrt(n);
    for (int i = 1; i <= n; i ++ ) scanf("%d", &w[i]), nums.push_back(w[i]);
    sort(nums.begin(), nums.end());
    nums.erase(unique(nums.begin(), nums.end()), nums.end());
    for (int i = 1; i <= n; i ++ )
        w[i] = lower_bound(nums.begin(), nums.end(), w[i]) - nums.begin();

    for (int i = 0; i < m; i ++ )
    {
        int l, r;
        scanf("%d%d", &l, &r);
        q[i] = {i, l, r};
    }
    sort(q, q + m, cmp);

    for (int x = 0; x < m;)
    {
        int y = x;
        while (y < m && get(q[y].l) == get(q[x].l)) y ++ ;
        int right = get(q[x].l) * len + len - 1;

        // 暴力求块内的询问
        while (x < y && q[x].r <= right)
        {
            LL res = 0;
            int id = q[x].id, l = q[x].l, r = q[x].r;
            for (int k = l; k <= r; k ++ ) add(w[k], res);
            ans[id] = res;
            for (int k = l; k <= r; k ++ ) {
                if(cnt[w[k]] == 2) res--;
                cnt[w[k]] -- ;
                if(cnt[w[k]] == 2) res++;
            }
            x ++ ;
        }

        // 求块外的询问
        LL res = 0;
        int i = right, j = right + 1;
        while (x < y)
        {
            int id = q[x].id, l = q[x].l, r = q[x].r;
            while (i < r) add(w[ ++ i], res);
            LL backup = res;
            while (j > l) add(w[ -- j], res);
            ans[id] = res;
            while (j < right + 1) {
                cnt[w[j ++ ]] -- ;
            }
            res = backup;
            x ++ ;
        }
        memset(cnt, 0, sizeof cnt);
    }

    for (int i = 0; i < m; i ++ ) printf("%lld\n", ans[i]);
    return 0;
}

3306. 有钱人买钻石

3305. 十亿分考

我随机不过去啊可恶

看到有人随机过了可能是我随的不太好

待补充

礼问正解是啥

3304. 不等式

idea:

相当于两种操作,1-对区间+1,2-询问总体最大值

离线操作然后离散化+差分

code:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int inf = 0x3f3f3f3f;

const int N = 700;

struct no {
    int op;
    int num;
};

vector<no> ques;
vector<int> vec;

ll pre[N];

signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);

    int n;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        string s;
        cin >> s >> s;
        int x;
        cin >> x;
        vec.push_back(x);
        vec.push_back(x - 1);
        vec.push_back(x + 1);

        if (s == "<") {
            ques.push_back({1, x});
        } else if (s == "<=") {
            ques.push_back({2, x});
        } else if (s == "=") {
            ques.push_back({3, x});
        } else if (s == ">=") {
            ques.push_back({4, x});
        } else if (s == ">") {
            ques.push_back({5, x});
        }
    }

    vec.push_back(-inf), vec.push_back(inf);
    sort(vec.begin(), vec.end());
    vec.erase(unique(vec.begin(), vec.end()), vec.end());

    for (auto[op, num] : ques) {
        int x = lower_bound(vec.begin(), vec.end(), num) - vec.begin();
        if (op == 1) { // <
            pre[1]++;
            pre[x]--;
        } else if (op == 2) { // <=
            pre[1]++;
            pre[x + 1]--;
        } else if (op == 3) { // =
            pre[x]++;
            pre[x + 1]--;
        } else if (op == 4) { // >=
            pre[x]++;
//            pre[vec.size()]--;
        } else if (op == 5) { // >
            pre[x + 1]++;
        }
    }

    int ans = -1;
    int sum = 0;
    int siz = vec.size() - 1;
    for (int i = 0; i <= siz; ++i) {
        sum += pre[i];
        ans = max(ans, sum);
    }

    cout << ans << endl;
    return 0;
}

3303. 1 的个数最多的整数

idea:

以l、r表示上下界,考虑0到r之间1个数最多的数时,1个数起码是r二进制位数-1(可以将r二进制1最高位变成0然后后面全赋成1)

加上下界,从高位到低位遍历,如果上下界从高位到低位开头一段的二进制一样,这段其实可以不考虑

对于剩下的部分,最坏情况就是将剩余最高位赋值成0,后面全1,特判能不能直接全1

code:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;


signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);

    ll T;
    cin >> T;
    for (ll ttt = 1; ttt <= T; ++ttt) {
        cout << "Case " << ttt << ": ";
        ll l, r;
        cin >> l >> r;
        ll pos = 0;
        ll res = 0;
        for (ll i = 63; i >= 0; --i) {
            if (((l >> i) & 1ll) + ((r >> i) & 1ll) == 1ll) {
                pos = i;
                break;
            } else {
                res += ((l >> i) & 1ll) * (1ll << i);
            }
        }
        bool flag = 1;
        for (int i = pos - 1; i >= 0; --i) {
            if (((r >> i) & 1ll) == 0) {
                flag = 0;
                break;
            }
        }
        if (flag) res += (r & ((1ll << (pos + 1)) - 1));
        else res += (1ll << (pos)) - 1ll;
//        cerr << pos << " " << (r & ((1ll <<( pos +1 )) - 1));
        cout << res << endl;
    }

}

3302. 打印

idea:

分奇偶dp

code:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const ll N = 1e7 + 10;

ll dp[N];

signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);

    ll n, x, y;
    cin >> n >> x >> y;

    memset(dp, 0x3f, sizeof dp);
    dp[0] = 0;
    dp[1] = x;

    for (ll i = 2; i <= n; ++i) {
        if (i & 1) {
            dp[i] = min(dp[i], dp[i - 1] + x);
            dp[i] = min(dp[i], dp[i / 2] + y + x);
            dp[i] = min(dp[i], dp[i / 2 + 1] + y + x);
        } else {
            dp[i] = min(dp[i], dp[i - 1] + x);
            dp[i] = min(dp[i], dp[i / 2] + y);
        }
    }

    cout << dp[n] << endl;
    return 0;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
华为机考 Python 是指华为公司在招聘过程中,通过使用机器进行考核Python编程能力。这种形式的考试采用了自动化的方式,可以帮助华为更高效地筛选出具备优秀Python编程能力的应聘者。 华为机考 Python 主要围绕Python编程语言进行,通过将考生放在一台电脑前,让其完成一系列的编程任务。这些任务可能包括基本的语法和控制语句的理解和运用,常见的数据结构和算法的实现,以及利用Python进行文件操作,网络编程等方面的能力。 相较于传统的面试方式,华为机考 Python 的好处在于它可以快速、客观地评估应聘者的Python编程能力。通过使用机器评分系统,可以对每个考生的答题情况进行统一的评估。这样一方面可以提高效率,节省人力成本,另一方面也可以避免因个人主观因素对考试结果的影响。 对于应聘者而言,参加华为机考 Python 不仅是一种展示自己编程能力的机会,也是锻炼自己代码编写和调试能力的机会。因此,在参加机考前,应聘者应该对Python编程语言进行充分的学习和准备,熟悉Python的语法规则、常用的数据结构和算法,并且掌握一定的调试技巧和如何解决常见编程问题的能力。 总之,华为机考 Python 是华为公司在招聘过程中采用的一种自动化考核方式,可以帮助公司更高效地筛选出具备优秀Python编程能力的应聘者。对于应聘者而言,参加机考前应该做好充分准备,以展示自己的编程实力。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值