由于前一段时间电脑坏了,所以把鸽的补回来~
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;
}