现在的位置: 首页 > 综合 > 正文

多校第七场解题报告

2018年02月21日 ⁄ 综合 ⁄ 共 3287字 ⁄ 字号 评论关闭

第六场各种数论题,对此没什么想写的(知道结论就是20行的事,无多少意义)故从第七场开始写

1001Hyperspace

传送门

曼哈顿距离多次求解,用2^k来维护最大最小值既能得解

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>

using namespace std;

#define clr(a, x) memset(a, x, sizeof(a))
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)


const int maxn = 60005;

struct node
{
    int d;
    int id;
    bool operator<(const pp a)const
    {
        return d<a.d;
    }
};

bool vis[maxn];
int p[10];

int main()
{
    int n,k;
    while(~scanf("%d %d",&n,&k))
    {
        priority_queue<pp>pq[1<<k];
        clr(vis,0);
        int all=(1<<k)-1;
        for(int i=1; i<=n; i++)
        {
            int op;
            scanf("%d",&op);
            if(op)
            {
                int del;
                scanf("%d",&del);
                vis[del]=1;
            }
            else
            {
                for(int j=0; j<k; j++)
                    scanf("%d",&p[j]);
                for(int s=0; s<=all; s++)
                {
                    pp t;
                    t.d=0;
                    t.id=i;
                    for(int j=0; j<k; j++)
                        if(s&(1<<j)) t.d+=p[j];
                        else t.d-=p[j];
                    pq[s].push(t);
                }
            }
            int ans=0;
            for(int s=0; s<=all; s++)
            {
                pp t1,t2;
                int t=all-s;
                while(!pq[s].empty())
                {
                    t1=pq[s].top();
                    if(!vis[t1.id]) break;
                    pq[s].pop();
                }
                while(!pq[t].empty())
                {
                    t2=pq[t].top();
                    if(!vis[t2.id]) break;
                    pq[t].pop();
                }
                if(!pq[s].empty()&&!pq[t].empty())
                    ans=max(ans,t1.d+t2.d);
            }
            printf("%d\n",ans);
        }
    }
}

1004Mutiples on a circle

传送门

比赛的时候因为感觉数据连在一起将远远超出long long而不敢下手,后来想了想开了取余表来记录,但是却因为位数问题伤透了心,结果写的好长好长,时间效率也不是太好。。

勉强算A了。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>

using namespace std;

const int MAXN = 50010;
int a[MAXN];
int end[MAXN];
int len[MAXN];
int b[2][220];

int getlen(int n)
{
    int ret = 0;
    while(n)
    {
        ret++;
        n/=10;
    }
    return ret;
}

int Ten[10];

int main()
{
    int n,k;
    while(scanf("%d%d",&n,&k) == 2)
    {
        for(int i = 1;i <= n;i++)
        {
            scanf("%d",&a[i]);
            len[i] = getlen(a[i]);
        }
        Ten[0] = 1;
        for(int i = 1;i < 5;i++)
            Ten[i] = Ten[i-1]*10%k;
        int now = 0;
        memset(b,0,sizeof(b));
        b[now][a[1]%k] = 1;
        long long ans = 0;
        ans += b[now][0];
        for(int i = 2;i <= n;i++)
        {
            memset(b[now^1],0,sizeof(b[now^1]));
            b[now^1][a[i]%k] = 1;
            for(int j = 0;j < k;j++)
            {
                if(b[now][j] == 0)continue;
                int ttt = j*Ten[len[i]]%k+a[i];
                ttt%=k;
                b[now^1][ttt] += b[now][j];
            }
            now^=1;
            ans += b[now][0];

        }
        end[n] = a[n]%k;
        int tmp = len[n];
        int SSSS = Ten[len[n]];
        for(int i = n-1;i>= 1;i--)
        {
            end[i] = a[i]*SSSS%k + end[i+1];
            end[i]%=k;
            tmp += len[i];
            SSSS = SSSS*Ten[len[i]]%k;
        }
        tmp = len[1];
        SSSS = Ten[len[1]];
        int tt = a[1]%k;
        for(int i = 1;i < n;i++)
        {
            b[now][end[i]]--;
            for(int j = 0;j < k;j++)
            {
                int ppp = (j*SSSS%k+tt)%k;
                if(ppp == 0)ans += b[now][j];
            }
            tt = tt*Ten[len[i+1]]+a[i+1];
            tt%=k;
            tmp+=len[i+1];
            SSSS = SSSS*Ten[len[i+1]]%k;
        }
        printf("%I64d\n",ans);

    }
    return 0;
}

1006Backup Plan

传送门

暴搞的一道题,唯一的问题是当m > n时需要讨论第二数据的内容(因为按题意每个数据库只有前两个有用途)然后所有内容按逆序写就可以了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>

using namespace std;

#define maxn 2005
#define INF 0xfffffff

int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n>m)
        {
            for(int i=1; i<=m; i++)
            {
                cout<<i<<' '<<n;
                if(i==1)
                {
                    for(int j=i+1; j<n; j++)
                        cout<<' '<<j;
                }
                else
                {
                    for(int j=i+1; j<n; j++)
                    {
                        cout<<' '<<j;
                    }
                    for(int j=1; j<i; j++)
                    {
                        cout<<' '<<j;
                    }
                }
                cout<<endl;
            }
        }
        else if(n==m)
        {
            for(int i=1; i<=m; i++)
            {
                cout<<i;
                if(i==1)
                {
                    for(int j=i+1; j<=n; j++)
                    {
                        cout<<' '<<j;
                    }
                }
                else
                {
                    for(int j=i+1; j<=n; j++)
                    {
                        cout<<' '<<j;
                    }
                    for(int j=1; j<i; j++)
                    {
                        cout<<' '<<j;
                    }
                }
                cout<<endl;
            }
        }
        else
        {
            int num=1,tmp=n,flag=0;
            for(int i=1; i<=m; i++)
            {
                int s=i%n?i%n:n;
                cout<<s;
                if(num<=n-1)
                {
                    cout<<' '<<tmp;
                    flag=tmp;
                    num++;
                    if(num==n)
                    {
                        num=1;
                        tmp--;
                        if(tmp==0)
                        {
                            flag=1;
                            tmp=n;
                        }
                    }
                }
                for(int j=1; j<=n; j++)
                {
                    if(j!=s&&j!=flag)
                        cout<<' '<<j;
                }
                cout<<endl;
            }
        }
    }
    return 0;
}

除去这三道,1003和1005也是能做的,可惜思路不够宽扩,硬生生的悲剧了。。

抱歉!评论已关闭.