问题 A: 灌水
时间限制: 1 Sec 内存限制: 256 MB Special Judge题目描述
输入
样例输入1:
3 1
样例输出1:
3 1 2
样例输入2:
4 1
样例输出2:
4 3 1 2
样例输入3:
8 17
样例输出3:
6 2 3 1 8 4 5 7
输出
提示
发现有一个小规律,如果最小的放在最大和次大的中间,对答案贡献最大,而把n个点按顺序排放,再用链表优化,之后从最左端找点看应该放在什么位置(就是判断他对答案的贡献),之后修改链表。如果当前x>=当前点的最大贡献,直接放到最右边,如果<判断一下。。直到x==0或跳出循环。若x!=0,cout<<-1即可。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define N 1000000
#define ll long long
using namespace std;
ll read()
{
ll sum=0,f=1;char x=getchar();
while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();}
while(x>='0'&&x<='9'){sum=(sum<<3)+(sum<<1)+x-'0';x=getchar();}
return sum*f;
}
int n,nex[N+5],fro[N+5];
ll x,a[N+5];
int main()
{
n=read();x=read();
if((ll)(n-2)*(n-1)/2<x){cout<<-1<<endl;exit(0);}
for(int i=1;i<=n;i++)
{
nex[i]=i+1;
fro[i]=i-1;
}
nex[n]=0;nex[0]=1;
for(int i=n-2;i>0;i--)
{
if(x>=i)
{
int k=n-i-1;
fro[nex[k]]=fro[k];
nex[fro[k]]=nex[k];
nex[k]=n;
fro[k]=fro[n];
nex[fro[k]]=k;
fro[n]=k;
x-=i;
}
else
{
int k=n-i-1,len=i-x;
int l=n-len;
fro[nex[k]]=fro[k];
nex[fro[k]]=nex[k];
nex[k]=l;
fro[k]=fro[l];
nex[fro[k]]=k;
fro[l]=k;
x=0;
break;
}
if(x==0)break;
}
if(x>0){cout<<-1<<endl;exit(0);}
for(int i=nex[0];i;i=nex[i])printf("%d ",i);
cout<<endl;
}