思路是:
每个元素按个数从小到大排序
如果剩余偶数个非 0 数量的元素,那么全局减 1
如果剩余奇数个非 0 数量的元素,那么除了最少的元素都减 1
只过了前三个部分分。
意向是尽量避免最后只剩一种元素(无解),所以奇数时那么干,偶数时感觉时间前后删都一样所以全局删。
#include<bits/stdc++.h>
using namespace std;
const int QAQ=1e3+7;
int t,s,x[QAQ],tong[QAQ*QAQ];
struct xxx {int cnt,s;} ;
xxx zhan[QAQ];
bool cmp(xxx a,xxx b) {return a.cnt<b.cnt;}
vector<int> ans[QAQ];
int read()
{
int x=0;
char c=getchar();
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x;
}
signed main()
{
cin>>t;
for(int i1=1;i1<=t;i1++)
{
s=read();
for(int i=1;i<=s;i++) x[i]=read(),tong[x[i]]++;
int cnt=0;
for(int i=1;i<=s;i++)
{
if(tong[x[i]])
{
zhan[++cnt]={tong[x[i]],x[i]};
tong[x[i]]=0;
}
}
sort(zhan+1,zhan+cnt+1,cmp);
int ci=0;
int siz=cnt,kai=1,wanle=0;
while(siz)
{
if(siz==1)
{
wanle=1;
break;
}
for(int i=kai;i<=cnt;i++)
{
if(zhan[i].cnt!=0)
{
kai=i;
break;
}
}
if(siz%2==0)
{
int cab=zhan[kai].cnt;
for(int i=1;i<=cab;i++)
{
++ci;
for(int i=kai;i<=cnt;i++)
{
ans[ci].push_back(zhan[i].s);
zhan[i].cnt--;
if(zhan[i].cnt==0) siz--;
}
}
}
else
{
++ci;
for(int i=kai+1;i<=cnt;i++)
{
ans[ci].push_back(zhan[i].s);
zhan[i].cnt--;
if(zhan[i].cnt==0) siz--;
}
for(int i=kai;i<cnt;i++)
if(zhan[i].cnt>zhan[i+1].cnt) swap(zhan[i],zhan[i+1]);
else break;
}
}
if(wanle)
{
puts("-1");
for(int i=1;i<=ci;i++) ans[i].clear();
}
else
{
printf("%d\n",ci);
for(int i=1;i<=ci;i++)
{
printf("%d ",ans[i].size());
for(int j=0;j<(int)ans[i].size();j++) printf("%d ",ans[i][j]);
ans[i].clear();
puts("");
}
}
}
return 0;
}