题意:
给定一组数据,要求分成两个等差数列,
且相对位置不可变,要求字典序最小。
若不能分成,则输出No solution
思路:
借助抽屉原理,如两个抽屉3个物品,必然有一个抽屉有两个以上的物品。
所以,3个,两个等差数列,必然有一个等差数列要接受2个以上的数据。
所以,只要取前三个数去推即可,a1 a2;a1 a3; a2 a3;去推等差数列即可,剩下的去组成另一个等差数列。
如果另一个组成失败,可以考虑拿末尾一个给另一个。
#include<bits/stdc++.h>
using namespace std;
int a[30005],b[30005];
int n;
int pd(int bs){
if(bs<=2){
return 1;
}
int i=0,s1,s2;
for(;i<n;i++){
if(b[i]!=1e9){
s1=b[i];
i++;
break;
}
}
for(;i<n;i++){
if(b[i]!=1e9){
s2=b[i];
i++;
break;
}
}
int qs=s2,cz=s2-s1;
for(;i<n;i++){
if(b[i]!=1e9){
if(b[i]-cz!=qs){
return 0;
}
qs=b[i];
}
}
return 1;
}
void csh(){
for(int i=0;i<n;i++){
a[i]=1e9;
b[i]=1e9;
}
}
int main(){
cin>>n;
vector<int> c(n+1);
for(int i=0;i<n;i++){
cin>>c[i];
}
int pan=0;
if(n==2){
cout<<c[0]<<endl;
cout<<c[1]<<endl;
}else{
for(int j=0;j<4;j++){
csh();
int i;
int cz,qs;
int bs=0,as=0;
if(j==0){
cz=c[1]-c[0];
qs=c[1];
a[0]=c[0];
a[1]=c[1];
as=2;
i=2;
}else if(j==1){
cz=c[2]-c[0];
qs=c[2];
a[0]=c[0];
a[2]=c[2];
b[1]=c[1];
as=2,bs=1;
i=3;
}else if(j==2){
cz=c[2]-c[1];
qs=c[2];
a[1]=c[1];
a[2]=c[2];
b[0]=c[0];
as=2,bs=1;
i=3;
}
for(;i<n;i++){
if(i==n-1&&bs==0){
b[i]=c[i];
break;
}
if(c[i]-cz==qs){
qs=c[i];
a[i]=c[i];
as++;
}else{
bs++;
b[i]=c[i];
}
}
int wa=n-1;
if(pd(bs)==0&&as>2){
while(a[wa]==1e9){
wa--;
}
b[wa]=a[wa];
as--,bs++;
a[wa]=1e9;
wa--;
}
if(pd(bs)==1&&bs!=0){
pan=1;
for(i=0;i<n;i++){
if(a[i]!=1e9){
cout<<a[i]<<" ";
}
}cout<<endl;
for(i=0;i<n;i++){
if(b[i]!=1e9){
cout<<b[i]<<" ";
}
}cout<<endl;
break;
}
}
if(pan==0){
cout<<"No solution"<<endl;
}
}
return 0;
}