rt.思路大概是按照正数和负数的个数设阈值讨论,发现正好能对上 31。但是 WA on pretest #2,求 hack/求调。当然不排除是做法假了,如果是的话希望大佬能指出。
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn=35;
const int inf=1e9;
int t,n,a[maxn];
//最大正数和最小负数
int main()
{
//freopen("test.in","r",stdin);
//freopen("test.out","w",stdout);
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int id1,id2;
int maxx=-inf,minn=inf;
int neg,k;//全负:1,全正:0
int cnt1=0,cnt0=0;//负数,正数
bool flag1=1,flag2=1;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(a[i]<0)flag1=0;
if(a[i]>0)flag2=0;
if(a[i]>=0)cnt1++;
else cnt0++;
if(a[i]>=0 && a[i]>maxx)maxx=max(maxx,a[i]),id1=i;
if(a[i]<0 && a[i]<minn)minn=min(minn,a[i]),id2=i;
}
if(flag1)
{
printf("%d\n",n-1);
for(int i=1;i<=n-1;i++)printf("%d %d\n",i+1,i);
continue;
}
if(flag2)
{
printf("%d\n",n-1);
for(int i=n-1;i>=1;i--)printf("%d %d\n",i,i+1);
continue;
}
//情况1:全部改成负数
bool flag=0;
if(cnt0>=cnt1)
{
if(cnt1<=7)flag=1;
else if(cnt1==8 && maxx<=16)flag=1;
else if(cnt1==9 && maxx<=8)flag=1;
else if(cnt1==10 && maxx<=4)flag=1;//全部改为负数
}
if(cnt1>cnt0)
{
if(cnt0==9 && minn<=-16)flag=1;
else if(cnt0==8 && minn<=-20)flag=1;//全部改为负数也可以
}
if(flag==1)
{
//puts("neg");
int y=0;
while(abs(a[id2])<maxx)
{
a[id2]*=2;
y++;
}
printf("%d\n",y+cnt1+n-1);
for(int i=1;i<=y;i++)printf("%d %d\n",id2,id2);
for(int i=1;i<=n;i++)
{
if(a[i]>=0)
{
printf("%d %d\n",i,id2);
}
}
for(int i=n-1;i>=1;i--)printf("%d %d\n",i,i+1);
}
else//全正
{
//puts("not neg");
int y=0;
while(abs(a[id1])<abs(minn))
{
a[id1]*=2;
y++;
}
printf("%d\n",y+cnt0+n-1);
for(int i=1;i<=y;i++)printf("%d %d\n",id1,id1);
for(int i=1;i<=n;i++)
{
if(a[i]<0)
{
printf("%d %d\n",i,id1);
}
}
for(int i=1;i<=n-1;i++)printf("%d %d\n",i+1,i);
}
}
return 0;
}