
先统计2的总数,如果是单数,则没有这样的k,否则,遍历计数,当2的数量=sum/2时,输出位置。
#include<stdio.h>
int main()
{
int a[1005],num,m,ans=0,n,sum;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
sum=0;
num=0;
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d",&a[i]);
if(a[i]==2) sum++;
}
if(sum%2==1) printf("-1\n");
else
{
ans=1;
for(int i=1;i<=m;i++)
{
if(a[i]==2) num++;
if(num==sum/2)
{
ans=i;
break;
}
}
printf("%d\n",ans);
}
}
return 0;
}

用并查集,如果不同跟,并集,同根则需要删除,统计需要删除的边,直到读完所有边,
#include<stdio.h>
int tree[200005];
int find(int x)
{
if(tree[x]==x) return x;
else
{
tree[x]=find(tree[x]);
return tree[x];
}
}
void merge(int x,int y)
{
x=find(x);y=find(y);
tree[x]=y;
}
int main()
{
int n,m,a,b,ans=0;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++) tree[i]=i;
while(m--)
{
scanf("%d %d",&a,&b);
if(find(a)==find(b)) ans++;
else
{
merge(a,b);
}
}
printf("%d",ans);
return 0;
}

通过不断翻转相邻数的符号,可以实现将任意两个数的符号翻转,所以先翻转所有负数的符号,如果没有负数留下,考虑是否翻转绝对值最小的负数和正数,如果没有负数留下,那么最大值为所有元素的绝对值和
#include<stdio.h>
int main()
{
int n,m,num,min,max,a[200005];
long long ans;
scanf("%d",&n);
while(n--)
{
num=0;
ans=0;
max=-1999999999;
min=1999999999;
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d",&a[i]);
if(a[i]<0)
{
num++;
if(a[i]>max) max=a[i];
ans+= (-1*a[i]);
}
else
{
if(a[i]<min) min=a[i];
ans+=a[i];
}
}
if(num%2==1)
{
ans+=max;
if(max+min<0) ans=ans-max-min-min;
else ans+=max;
}
printf("%lld\n",ans);
}
return 0;
}