2022.10.29每日刷题打卡(补

由于前一段时间电脑坏了,所以把鸽的补回来~

Orray

题意:对a重新排序使得a的前缀或和最大

思路:

题目时间限制2s,所以可以稍微暴力地去写。

要使前缀或和,那么第一个位置一定要放数组最大的值,剩下的排序我们可以遍历一下去找到或最大的结果找的一个可以存一个,最后没存进去的按顺序输出就可以啦。

#include <bits/stdc++.h>

void solve()
{
    int n;
    std::cin >> n;
    std::vector<int> a(n);
    std::vector<bool> vis(n, false);
    for(int &ai : a) std::cin >> ai;
    std::sort(a.begin(), a.end());
    int ans = a.back();
    std::vector<int> res;
    res.push_back(ans);
    for(int i = 0; i < n; i++){
        int f = 0;
        bool fy = 0;
        for(int j = 1; j < n; j++)
            if(!vis[f] && (ans | a[j]) > (ans | a[f]))
                f = j, fy = 1;
        if(fy) ans |= a[f], vis[f] = 1, res.push_back(a[f]);
    }
    for(auto x : res) std::cout << x << " ";
    for(int i = 0; i < n - 1; i++) if(!vis[i]) std::cout << a[i] << " ";
    std::cout << "\n";
}

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int t;
    std::cin >> t;

    while (t--)
    {
        solve();
    }

    return 0;
}

等等.....这题这样写会TLE

其实仔细想想就可以想到,2e5的数据这样跑必T,那么怎么优化呢,其实可以考虑到如果我们标记的fy没有变化那么说明这个时候已经找不到最大的或值,所以在这里直接结束循环即可。

#include <bits/stdc++.h>

void solve()
{
    int n;
    std::cin >> n;
    std::vector<int> a(n);
    std::vector<bool> vis(n, false);
    for(int &ai : a) std::cin >> ai;
    std::sort(a.begin(), a.end());
    int ans = a.back();
    std::vector<int> res;
    res.push_back(ans);
    for(int i = 0; i < n; i++){
        int f = 0, fy = 0;
        for(int j = 1; j < n; j++)
            if(!vis[f] && (ans | a[j]) > (ans | a[f]))
                f = j, fy = 1;
        if(fy) ans |= a[f], vis[f] = 1, res.push_back(a[f]);
        else break;
    }
    for(auto x : res) std::cout << x << " ";
    for(int i = 0; i < n - 1; i++) if(!vis[i]) std::cout << a[i] << " ";
    std::cout << "\n";
}

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int t;
    std::cin >> t;

    while (t--)
    {
        solve();
    }

    return 0;
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值