HDU4671 找规律排列问题

来源:互联网 发布:linux 禁用端口 编辑:程序博客网 时间:2024/05/28 06:04

Source: 2013 Multi-University Training Contest 7 1006

题目大意: 题目意思还是比较麻烦的,当时做多校的时候询问题意的人就特别多。给你n个服务器,m个数据库。每个数据库有一个序列,每个序列有n个数,作为优先请求的顺寻,例如n=5,m=3.对于 第一个数据库假设排列是 1 2 3 4 5那么如果1号服务器没坏,这个数据库就向一号服务器递交申请使用,这时候2号是空闲的。如果一坏了,那么将使用二号,以此类推。那么m个数据库就会有m个n个数的排列。但是这样的排列必须满足一定得条件,就是对于一个时刻,最多被使用服务器的次数减去最少被使用的服务器次数不能超过1(<=1)。这就是说平衡每个服务器的使用,尽可能使得工作平均。同时如果假定一个服务器坏掉(最多一个),这是的工作状态也是满足这个平衡条件的(坏掉的不计入使用次数)。输出这样的排列,Special Judge,输出一种可能即可。

给的样例 n=5 m=3

2 4 3 1 5        如果都没坏, 1,2,3使用1次,4,5使用0,最大不超过1. 如果4,5坏掉,对使用暂时没用影响。如果1坏了,那么2,5,3被使用……2,3坏掉一样1 5 4 2 33 5 2 4 1

思路:因为要尽可能使每种服务器使用均衡,对于第一次序的,只需要按照1,2,3……n,1,2,3……这样排列就好了。

例如 n=6 m=3     为    n=3 m=6 为  

1                                    1

2                                    2

3                                    3

                                      1

                                      2

                                      3

因为最多坏掉一个,其实只是将第二列左移到坏掉的一列上,其实只需要考虑前两列。因为我们的排序时尽可能使小的号码使用先,所以号码大的必然比小的使用次数少。那么我们对于替换就优先使用大序号替换。 我们再开一个数组t,记录当前替换序号,初始化为n,我们只需要讨论一号工作站相同的情况的第二列,设为a。 如果第二列与第一列不同 t[a]加入第二列,t[a]--;如果与第一列相同,t[a]-1加入再--。之后两列拍好,后面n-2列只要不重复即可。


代码:

#include<iostream>#include<cstdio>#include<cstring>using namespace std;int s[102];int a[102][3];int main(){    int n,m;  //n为sever m 为database    while(scanf("%d%d",&n,&m)!=EOF)    {        memset(s,0,sizeof(s));        memset(a,0,sizeof(a));        int temp=0;        for(int i=1; i<=m; i++)        {            a[i][1]=(temp)%n+1;            temp=(temp)%n+1;        }        temp=n;        for(int i=1; i<=n; i++)            s[i]=n;        for(int i=1; i<=m; i++)        {            int t=a[i][1];            if(a[i][1]!=s[t])            {                a[i][2]=(s[t]);                s[t]=(s[t]-2+n)%n+1;            }            else            {                a[i][2]=(s[t]-2+n)%n+1;                s[t]=(s[t]-2+n)%n+1;                s[t]=(s[t]-2+n)%n+1;            }        }        int temp1=1;        for(int i=1; i<=m; i++)        {            temp1=1;            for(int j=1; j<=n; j++)            {                if(j==1||j==2) cout<<a[i][j]<<" ";                else                {                    while(temp1==a[i][1]||temp1==a[i][2])                        temp1++;                    cout<<temp1;                    if(j!=n)cout<<" ";                    temp1++;                }            }            cout<<endl;        }    }}


原创粉丝点击