多校 2013 7

F

n 个服务器 m个数据库

要求是一个服务器坏了 其他服务器调用的次数之差小于=1

要的是数据库调用服务器的序列

重要的是 前 2 列

第一列 1 ~n  一直循环 第二列  就要2种情况分类  n>=m  放n 否则 n~1循环

#include<stdio.h>
#include<string.h>
#include<algorithm>

using namespace std;


int z[110][110];
bool vis[110];

int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
            if(n>=m)
            {
                for(int i=1;i<=m;i++)
                {
                    z[i][1]=i;
                    z[i][2]=n;
                    if(z[i][1]==n)
                        z[i][2]=1;
                }
            }
             else
             {
                int k=n;

                for(int i=1;i<=m;i++)
                {
                    z[i][1]=i%n;
                    z[i][2]=k;
                    if(i%n==0)
                    {
                        z[i][1]=n;
                    }
                    if(z[i][1]==z[i][2])
                    {
                        k--;
                        if(k==0)
                            k=n;
                        z[i][2]=k;
                    }
                }
            }
            for(int i=1;i<=m;i++)
            {
                memset(vis,0,sizeof(vis));
                vis[z[i][2]]=1;
                vis[z[i][1]]=1;
                int k=1;

                for(int j=3;j<=n;j++)
                {
                    while(vis[k]==1)
                        k++;
                    z[i][j]=k;
                    vis[k]=1;
                }
            }
            for(int i=1;i<=m;i++)
            {
                for(int j=1;j<n;j++)
                    printf("%d ",z[i][j]);
                printf("%d\n",z[i][n]);
            }
    }

    return 0;
}
View Code

A

n  m

n个操作 0 x y  加入x  y这个点  

            1  a     删掉a这个操作的点 

求最远曼哈顿距离 

m 维度

|xi-xj|+|yi-yj|

答案有4种可能

(xi+yi)-(xj+yj)

然后四种可能的形式是一样的    那么只要维护2^m 次方个形式

multiset

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<set>
#include<iterator>

using namespace std;

#define MAXN 60010
multiset<int>mst[50];

int num[MAXN][6];

int main()
{

    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        int en1=1<<5;
        int en=1<<m;
        for(int i=0;i<en1;i++)
            mst[i].clear();

        for(int i=1;i<=n;i++)
        {
            int op;
            scanf("%d",&op);
            if(op==0)
            {
                for(int j=0;j<m;j++)
                    scanf("%d",&num[i][j]);

                for(int j=0;j<en;j++)
                {
                    int sum=0;
                    for(int k=0;k<m;k++)
                    {
                        if(j&(1<<k))
                            sum=sum+num[i][k];
                        else
                            sum=sum-num[i][k];
                    }
                    mst[j].insert(sum);
                }
            }
            else
            {
                int ind;
                scanf("%d",&ind);
                for(int j=0;j<en;j++)
                {
                    int sum=0;
                    for(int k=0;k<m;k++)
                    {
                        if(j&(1<<k))
                            sum=sum+num[ind][k];
                        else
                            sum=sum-num[ind][k];
                    }
                    multiset<int>::iterator it;
                    it=mst[j].find(sum);
                    mst[j].erase(it);
                }
            }
            int ans=0;
            for(int j=0;j<en;j++)
            {
                multiset<int>::iterator it1,it2;
                it1=mst[j].begin();
                it2=mst[j].end();
                it2--;
                ans=max(ans,(*it2)-(*it1));
            }
            printf("%d\n",ans);
        }
    }
    return 0;
}
View Code

D

n个数  顺时针 组成的数 要%m =0

有多少种

dp[i][j]   以第 i 个数为结尾 余数为j  的数目

dp[i][ j* 10^(x)+val[i] %m ]+= dp[i-1][j]

重复了就减掉

#include<stdio.h>
#include<string.h>
#include<algorithm>

using namespace std;

#define MAXN 50020

int z[MAXN];
int dp[MAXN][210];
int te[MAXN<<2];
int l[1010];

int main()
{

    int n,k;
    for(int i=0;i<=1000;i++)
    {
        if(i<10)
            l[i]=1;
        else if(i<100)
            l[i]=2;
        else if(i<1000)
            l[i]=3;
        else
            l[i]=4;
    }

    while(scanf("%d%d",&n,&k)!=EOF)
    {
        te[0]=1;
        int en=n<<2;
        for(int i=1;i<=en;i++)
            te[i]=(te[i-1]*10)%k;
        for(int i=1;i<=n;i++)
            scanf("%d",&z[i]);
        z[n+1]=z[1];
        for(int i=1;i<=n;i++)
            for(int j=0;j<k;j++)
                dp[i][j]=0;
        int sum=0;
        int len=0;
        for(int i=n+1;i>1;i--)
        {
            sum=(sum+z[i]*te[len])%k;
            len=len+l[z[i]];
            dp[1][sum]++;
        }
        for(int i=2;i<=n;i++)
        {
            for(int j=0;j<k;j++)
            {
                dp[i][(z[i]+j*te[l[z[i]]])%k]+=dp[i-1][j];
            }
            sum=(sum*te[l[z[i]]]+z[i])%k;
            dp[i][sum]--;
            dp[i][z[i]%k]++;
            sum=((sum-te[len]*z[i])%k+k)%k;
        }
        long long  ans=0;
        for(int i=1;i<=n;i++)
            ans=ans+dp[i][0];
        printf("%lld\n",ans);

    }
    return 0;
}
View Code

 

 

 

posted on 2017-07-19 15:18  HelloWorld!--By-MJY  阅读(110)  评论(0编辑  收藏  举报

导航