2017.10.31测试

来源:互联网 发布:准确的平特一肖算法 编辑:程序博客网 时间:2024/06/09 06:27

分数:100+50+0=150
今天开了一橙一金紫,美滋滋
还合了两橙


题解

T1 cleaner

给出正方形“半径”,问什么位置能使正方形中各点权值和最大?
注:背景大图为[0,1024]*[0,1024],给出N个有权值的点,正方形中心可以在边界上

分析:矩阵前缀和,已知d直接扫一遍中心就行了

#include<bits/stdc++.h>#define ll long long#define m(a) memset(a,0,sizeof(a))using namespace std;int read(){    int x=0,f=1;char c;    for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-1;    for(;isdigit(c);c=getchar())x=(x<<3)+(x<<1)+c-'0';    return x*f;}int d,x,y,n,w;int maxm=0,ans=0;int a[1100][1100];int f[1100][1100],fn[1100][1100];int main(){//  freopen("cleaner.in","r",stdin);//  freopen("cleaner.out","w",stdout);    d=read();n=read();    for(int i=1;i<=n;i++){        x=read();y=read();w=read();        a[x][y]=w;    }    for(int i=0;i<=2000;i++)        for(int j=0;j<=2000;j++){            f[i][j]=a[i][j]+f[i][j-1]+f[i-1][j]-f[i-1][j-1];        }    for(int i=0;i<=1024;i++)        for(int j=0;j<=1024;j++){            fn[i][j]=f[i+d][j+d]-f[i+d][j-d-1]-f[i-d-1][j+d]+f[i-d-1][j-d-1];            if(fn[i][j]==maxm){                ans++;//if(maxm=942)cout<<i<<" "<<j<<endl;//              cout<<1<<" "<<i<<" "<<j<<endl;            }            if(fn[i][j]>maxm){                ans=1;                maxm=fn[i][j];//              cout<<maxm<<" "<<i<<" "<<j<<endl;            }        }    cout<<ans<<" "<<maxm;}

T2 friend(bzoj 2143)

一张矩形图划分为N*M格,可以花费bij从某格跳到距这格曼哈顿距离不超过aij的点上,给出三个起始点X、Y、Z坐标,问在其中哪个点集合代价最小
开了5 s!
我我我觉得自己跑不过的时候就直接cout“NO”了!于是只有50,想看看到底能拿多少可是bzoj他不给分啊!而且居然还没有NO的分!

调试整整1D…自己可能是个假人
就是不建边跑迪杰斯特拉,中途break就行了心累

#include<bits/stdc++.h>#define ll long long#define m(a) memset(a,0,sizeof(a))#define inf 100000000000000097using namespace std;inline char read() {    static const int IN_LEN = 1024 * 1024;    static char buf[IN_LEN], *s, *t;    if (s == t) {        t = (s = buf) + fread(buf, 1, IN_LEN, stdin);        if (s == t) return -1;    }    return *s++;}template<class T>inline void R(T &x) {    static char c;    static bool iosig;    for (c = read(), iosig = false; !isdigit(c); c = read()) {        if (c == -1) return ;        if (c == '-') iosig = true;     }    for (x = 0; isdigit(c); c = read())         x = ((x << 2) + x << 1) + (c ^ '0');    if (iosig) x = -x;}int n,m,ct,x,y,tot;int a[42505],b[42505],xx[8];ll dis[42505],len[8][8];bool vis[42505];char as[4]={'0','X','Y','Z'};inline int calc(int x,int y){    return (x-1)*ct+y;}inline void djisktra(int xxx){    priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > > q;    int x,xl,v,aa,bb,maxm,minm,rt;    rt=xx[xxx];    m(vis);    for(int i=1;i<=tot+1;i++)dis[i]=inf;    dis[rt]=0;    q.push(make_pair(0,rt));    while(!q.empty()){        if(vis[xx[1]]&&vis[xx[2]]&&vis[xx[3]])break;        do {            x=q.top().second;q.pop();           }while(vis[x]);        vis[x]=1;        aa=x/ct+1;        bb=x-(aa-1)*ct;        maxm=min(n,aa+a[x]);        for(int i=max(1,aa-a[x]);i<=maxm;i++){            xl=abs(i-aa);            minm=min(m,bb+a[x]-xl);            for(int j=max(1,bb-a[x]+xl);j<=minm;j++){                v=calc(i,j);                if(dis[v]>dis[x]+b[x]){                    dis[v]=dis[x]+b[x];                    q.push(make_pair(dis[v],v));                }            }        }    }    for(int i=1;i<=3;i++){        if(i==xxx)continue;        len[xxx][i]=dis[xx[i]];    }}int main(){//  freopen("x.in","r",stdin);    ios::sync_with_stdio(false);    cin.tie(NULL);    R(n);R(m);    ct=m+1;tot=calc(n,m);    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)            R(a[calc(i,j)]);    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)            R(b[calc(i,j)]);    for(int i=1;i<=3;i++){        R(x);R(y);        int tmp=calc(x,y);        xx[i]=tmp;    }    for(int i=1;i<=3;i++)djisktra(i);    ll minn=1e18,ans[5],sign=0;m(ans);    for(int i=1;i<=3;i++){        for(int j=1;j<=3;j++){            if(i==j)continue;            ans[i]+=len[j][i];        }    }    for(int i=1;i<=3;i++){        if(ans[i]<minn){            sign=i;            minn=ans[i];        }    }    cout<<as[sign]<<endl;    cout<<minn;}

T3 ribbon

对一条最长为1e9的纸带做出N次修改,第i次用颜色i替换liri区间中的所有颜色,问最后还剩多少颜色?
注:N<=1e6

我们可以离散化之后任意处置,不管是线段树、倒着修改、并查集优化都可以很轻松地A掉,(不想说出我的故事)

#include<bits/stdc++.h>using namespace std;int read(){    int x=0,f=1;char c;    for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-1;    for(;isdigit(c);c=getchar())x=(x<<3)+(x<<1)+c-'0';    return x*f;}int n;int tot=0,maxx=0,ans=0;int a[4000005],fa[4000005];bool vis[4000005];struct note{    int x,y;}e[10000005];void lsh(){//离散化     tot=2*n;    sort(a+1,a+tot+1);    tot=unique(a+1,a+tot+1)-a-1;//去重     for(int i=1;i<=n;i++){        e[i].x=lower_bound(a+1,a+tot+1,e[i].x)-a;         e[i].y=lower_bound(a+1,a+tot+1,e[i].y)-a;        maxx=max(maxx,e[i].y);    }}int get_fa(int x){    if(!vis[x]){        return x;    }    return fa[x]=get_fa(fa[x]);}int main(){    n=read();    for(int i=1;i<=n;i++){        e[n-i+1].x=read()+1;e[n-i+1].y=read();        a[i*2-1]=e[n-i+1].x;a[i*2]=e[n-i+1].y;    }    lsh();    for(int i=1;i<=tot;i++) fa[i]=i+1;    for(int i=1;i<=n;i++){        bool sign=0;        for(int j=e[i].x;j<=e[i].y;j++){            if(!vis[j]){                vis[j]=1;                sign=1;            }            else {                fa[j]=get_fa(fa[j]);                j=fa[j]-1;            }        }        if(sign)ans++;    }    cout<<ans;}
原创粉丝点击