Codeforces Round 889 (Div. 2) C1 - C2
题意:
有
hard-version和easy-version有共同之处,所以放在一起讲了。
思路:
首先,我们可以大致分成三种情况讨论:全为正数,全为负数,以及有正有负(在这里0不会对最终答案产生影响,可以放进任意一种情况里)
比较容易看出,对于全正的,我们只需要从左到右把
相对应的,对于全负的情况,我们只需要从右到左把
可以容易看出,上面两种处理最多只需要操作19次,同时满足了两个版本的要求。
那么接着考虑有正有负。
对于easy-version,可以对数组中正数和负数的个数进行统计,同时记录正数中的最大值和负数中的最小值,如果正数个数大于负数个数,那么我们只需要让正数的最大值进行自加,直到大于负数最小值的绝对值,然后再把它加到所有负数上,就可以让所有负数变成正数,然后继续上面全正的操作即可。如果负数个数大于正数个数则同理。
上面方案中最坏的情况就是
思考更好的方法,观察可以发现,对于上面的情况,如果我们直接把
事实上上面的极限个数还会随着数组大小变化,但这个方法只会更优,且一定满足条件,所以不用继续优化也可以。
void QAQ(){
int n;
cin >> n;
int minn = INF, maxx = -INF;
vector<int> num(n + 1);
for(int i = 1; i <= n; i ++){
cin >> num[i];
maxx = max(maxx, num[i]);
minn = min(minn, num[i]);
}
queue<pii> op;
if(minn >= 0){//全正
for(int i = 1; i < n; i ++){
// cout << i + 1 << " " << i << endl;
op.push({i + 1, i});
}
}
else if(maxx <= 0){//全负
for(int i = n; i > 1; i --){
// cout << i - 1 << " " << i << endl;
op.push({i - 1, i});
}
}
else{//有正有负另外统计
int a = 0, b = 0, aa = 0, bb = 0;
int acnt = 0, bcnt = 0;
for(int i = 1; i <= n; i ++){
if(num[i] > 0){
if(num[i] > a){
aa = i, a = num[i];
}
acnt ++;
}
else if(num[i] < 0){
if(num[i] < b){
bb = i, b = num[i];
}
bcnt ++;
}
}
//如果是easy-version直接看最后的else也可以
if(abs(a) > abs(b) && bcnt <= 12){
for(int i = 1; i <= n; i ++){
if(num[i] < 0){
op.push({i, aa});
}
}
for(int i = 1; i < n; i ++){
op.push({i + 1, i});
}
}
else if(abs(b) > abs(a) && acnt <= 12){
for(int i = 1; i <= n; i ++){
if(num[i] > 0){
op.push({i, bb});
}
}
for(int i = n; i > 1; i --){
// cout << i - 1 << " " << i << endl;
op.push({i - 1, i});
}
}
else{
if(acnt > bcnt){
//正数多
while(abs(a) < abs(b)){
a += a;
op.push({aa, aa});
}
for(int i = 1; i <= n; i ++){
if(num[i] < 0){
op.push({i, aa});
}
}
for(int i = 1; i < n; i ++){
op.push({i + 1, i});
}
}
else{
while(abs(b) < abs(a)){
b += b;
op.push({bb, bb});
}
for(int i = 1; i <= n; i ++){
if(num[i] > 0){
op.push({i, bb});
}
}
for(int i = n; i > 1; i --){
// cout << i - 1 << " " << i << endl;
op.push({i - 1, i});
}
}
}
}
cout << op.size() << endl;
while(!op.empty()){
int x, y;
tie(x, y) = op.front();
op.pop();
cout << x << " " << y << endl;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】