| ||||||||||||||
题意:有N个选手,M个分值,前K个人有P个不同的分值。当然前者分值必然不小于后者。问这N个人是否满足这样的要求。满足则输出任意一组情况。不满足则Wrong。
题解:我们先判断最小的分值(d-1)*d/2=min。注意可以分值为0。然后如果d==1的话。就有两种情况判断,如果k==n,那么p就必须平均分配给k个人。也就是p%k==0,否则W.如果n!=k。并且剩下的分值p-(p/k*K)还大于前者的话也是W.否则就直接分配ans=p/k给前k个。然后再递减分配给剩下的人。绝对会满足条件。
若是d!=1的话。就按0,1,2,3分配给后n-1个人,那么第一个人就是剩下的p。保证p会大于后面的人的分值。因为前面已经进行判断过了。然后后面的lose统一分配0就OK了。有可能会与比我的算法更好的构造方式。欢迎指教。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
#include <map>
#include <stack>
#include <list>
#include <vector>
#define LL __int64
#define EPS 1e-8
using namespace std;
int a[10010];
int main()
{
int n,p,k,d,i;
//freopen("out.txt","w",stdout);
while (~scanf("%d%d%d%d",&n,&p,&k,&d))
{
//int max=(2*k-d+1)*d/2+(k-d)*k;
int min=(d-1)*d/2;
if (p<min)
{
puts("Wrong information");
continue;
}
int i=0;int ans;
if (d==1)
{
ans=p/k;
if ((p-ans*k>0 && (n-k)==0) || ((n-k)!=0 && (p-ans*k)/(n-k)>ans))
{
puts("Wrong information");continue;
}
else
{
for (i=1;i<=k;i++)
cout<<ans<<endl;
int s=p-ans*k;
for (i=1;i<=n-k;i++)
{
if (s>ans)
{
cout<<ans<<endl;
s-=ans;
}
else
{
cout<<s<<endl;
s-=s;
}
}
}
}
else
{
for (i=0;i<d-1;i++)
{
a[i]=i;
p-=i;
}
if (p>0) cout<<p<<endl;
for (i=d-2;i>=0;i--)
cout<<a[i]<<endl;
for (i=1;i<=n-d;i++)
cout<<"0"<<endl;
}
}
return 0;
}