HDU 4671 Backup Plan(水題)
1791 ワード
标题:(すでに本人が転化した...)M個のデータ局、N個のサーバがあり、各データ局には1つのシーケンスがあり、このシーケンスはそのデータ局が自分のデータバックアップを保存する際の優先順位であり、1番目のサーバが壊れた場合、2番目のサーバに自分のバックアップを保存し、このように自分のバックアップを保存できるまで保存する.これにより、サーバごとに一定数のデータ・ステーションのデータ・バックアップが格納されます.
たとえば、すべてのサーバが不良ではなく、Aデータ・ステーションとBデータ・ステーションが所有するサーバ優先度シーケンスの1番目がサーバ2である場合、2番目のサーバは、Aデータ・ステーションとBデータ・ステーションのデータが格納されているため、2つのバックアップを格納します.
現在、各サーバに格納されているバックアップ数はA[i]であり、任意のiが要求され、jが|A[i]-A[j]|<=1を満たすことが記録されている.
ただし,サーバごとに壊れる可能性があり,任意に1つのサーバを壊せるように要求された場合には任意i,jが|A[i]-A[j]|<=1を満たす.上記の条件が成立するように、すべてのデータ局の優先順位シーケンスを出力します.
考え方:サーバが壊れていないとき、サーバが1つのデータ局の1位になるたびに、このサーバが格納しているバックアップが1回以上あることに気づく.つまり、1つのサーバがKつのデータ局の1位になると、A[i]=Kとなる.テーマはM粒のキャンディがあり、N個の箱があり、各箱にA[i]粒のキャンディが入っている.要求|A[i]-A[j]|<=1、これはとてもやりやすくて、キャンディが均一に配分すればいいです.
例えば10個のキャンディ、3個の箱であれば、4,3,3に分配すればよい.
では、サーバーが壊れたら、1位のときは2位のものに代わっています.その中の1箱のキャンディを回収し、その箱を撤去して、回収したキャンディを再均一に分配することに相当します.例えば4,3,3,今2箱目のキャンディを回収して再配分すると5,5に配分されます.
考えが分かれば、1位の回数を均等に配分し、1位の数字ごとに残りの数字を均等に配分すればいい.先頭の2つを特定すると、後ろは任意に並べることができます.毎回1つのサーバしか壊れないので、前の2つのサーバだけが有効です.
たとえば、すべてのサーバが不良ではなく、Aデータ・ステーションとBデータ・ステーションが所有するサーバ優先度シーケンスの1番目がサーバ2である場合、2番目のサーバは、Aデータ・ステーションとBデータ・ステーションのデータが格納されているため、2つのバックアップを格納します.
現在、各サーバに格納されているバックアップ数はA[i]であり、任意のiが要求され、jが|A[i]-A[j]|<=1を満たすことが記録されている.
ただし,サーバごとに壊れる可能性があり,任意に1つのサーバを壊せるように要求された場合には任意i,jが|A[i]-A[j]|<=1を満たす.上記の条件が成立するように、すべてのデータ局の優先順位シーケンスを出力します.
考え方:サーバが壊れていないとき、サーバが1つのデータ局の1位になるたびに、このサーバが格納しているバックアップが1回以上あることに気づく.つまり、1つのサーバがKつのデータ局の1位になると、A[i]=Kとなる.テーマはM粒のキャンディがあり、N個の箱があり、各箱にA[i]粒のキャンディが入っている.要求|A[i]-A[j]|<=1、これはとてもやりやすくて、キャンディが均一に配分すればいいです.
例えば10個のキャンディ、3個の箱であれば、4,3,3に分配すればよい.
では、サーバーが壊れたら、1位のときは2位のものに代わっています.その中の1箱のキャンディを回収し、その箱を撤去して、回収したキャンディを再均一に分配することに相当します.例えば4,3,3,今2箱目のキャンディを回収して再配分すると5,5に配分されます.
考えが分かれば、1位の回数を均等に配分し、1位の数字ごとに残りの数字を均等に配分すればいい.先頭の2つを特定すると、後ろは任意に並べることができます.毎回1つのサーバしか壊れないので、前の2つのサーバだけが有効です.
#include<cstdio>
#include<cstring>
int N,M;
int f2[105][2];//
int A[105];
int main()
{
while(~scanf("%d %d",&N,&M))
{
memset(A,0,sizeof(A));
memset(f2,0,sizeof(f2));
for(int i=1;i<=N;++i)// A[i]
{
A[i]=M/N;//
if(M%N>=i) ++A[i];//
}
int cnt=1;
for(int i=1;i<=N;++i)
for(int j=1,k=N;j<=A[i];++j,--k)
{
while(i==k || k==0)
{
if(i==k) --k;
if(k==0) k=N;
}
f2[cnt][0]=i,f2[cnt][1]=k,++cnt;//
}
for(int i=1;i<=M;++i)//
{
printf("%d %d",f2[i][0],f2[i][1]);
for(int j=1;j<=N;++j) if(j!=f2[i][0] && j!=f2[i][1]) printf(" %d",j);
printf("
");
}
}
return 0;
}