码迷,mamicode.com
首页 > 其他好文 > 详细

9.21 正睿普及2

时间:2018-09-25 22:59:16      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:gre   ++   连通   read   clu   bool   ESS   cst   最小   

目录


2018.9.21 正睿普及2

时间:3.5h
期望得分:100+100+20+20
实际得分:100+100+30+20

比赛链接

A Non-max suppression(矩形面积并)

题目链接

//阅读理解题。就是排个序,然后求一下矩形面积交/并。
#include <cstdio>
#include <cctype>
#include <vector>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 200000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=2005;

int id[N],pos[N];
bool del[N];
std::vector<int> ans;
char IN[MAXIN],*SS=IN,*TT=IN;
struct Matrix
{
    int id,pc,x,y,w,h; LL S;
    int LDx() {return x-w;}
    int LDy() {return y-h;}
    void Init() {S=4ll*w*h;}
    bool operator <(const Matrix &a)const
    {
        return pc<a.pc;
    }
}mat[N];

inline int read()
{
    int now=0,f=1;register char c=gc();
    for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now*f;
}
bool cmp(int i,int j)
{
    return mat[i].LDy()==mat[j].LDy()?mat[i].LDx()<mat[j].LDx():mat[i].LDy()<mat[j].LDy();
}
bool Check(Matrix a,Matrix b,int aa,int bb)
{
    if(pos[aa]>pos[bb]) std::swap(a,b);
    if(a.LDx()>b.LDx())
    {
        int rdx=b.x+b.w, rdy=b.y-b.h;
        int lux=a.x-a.w, luy=a.y+a.h;
        rdx=std::min(rdx,a.x+a.w), luy=std::min(luy,b.y+b.h);
        LL s1=a.S, s2=b.S, sj=1ll*(rdx-lux)*(luy-rdy);
        return rdx-lux>=0 && s1+s2<3*sj;
    }
    else
    {
        int ldx=b.x-b.w, ldy=b.y-b.h;
        int rux=a.x+a.w, ruy=a.y+a.h;
        rux=std::min(rux,b.x+b.w), ruy=std::min(ruy,b.y+b.h);
        LL s1=a.S, s2=b.S, sj=1ll*(rux-ldx)*(ruy-ldy);
        return rux-ldx>=0 && s1+s2<3*sj;
    }
}

int main()
{
//  freopen("ex_suppresion1.in","r",stdin);
//  freopen("my.out","w",stdout);

    int n=read();
    for(int i=1; i<=n; ++i) mat[i]=(Matrix){i,read(),read(),read(),read(),read()},mat[i].Init();
    std::sort(mat+1,mat+1+n);

    int now=1; mat[n+1].pc=1e7;
    while(mat[now].pc<600000) ++now;
    if(now>n) return 0;

    for(int i=now; i<=n; ++i) id[i]=i;
    std::sort(id+now,id+1+n,cmp);
    for(int i=now; i<=n; ++i) pos[id[i]]=i;
    for(int i=n; i>=now; --i)
    {
        if(del[i]) continue;
        ans.push_back(mat[i].id);
        for(int j=i-1; j>=now; --j)
        {
            if(del[j]) continue;
            if(Check(mat[i],mat[j],i,j)) del[j]=1;//, printf("%d(%d) del %d(%d)\n",i,mat[i].id,j,mat[j].id);
        }
    }
    std::sort(ans.begin(),ans.end());
    for(int i=0,l=ans.size(); i<l; ++i) printf("%d ",ans[i]);

    return 0;
}/*
6
700000 456 654 132 321
520000 255 548 102 99
905004 600 405 456 210
650474 511 547 500 45
957867 200 200 100 150
741567 1050 451 900 386
*/

B 摩斯电码(DP)

题目链接

//很恶心→_→
#include <cstdio>
#include <cstring>
#include <algorithm>
#define mod 1000000007
typedef long long LL;
const int N=1e6+5;
const char ZZ[5]="1100",RR[5]="010";
const char ban[4][5]={"1111","0011","0101","1110"};

int n;
LL f[N][2];
char s[N];

bool Diff(int p,char c)
{
    if(c=='z')
    {
        if(p+3>n) return 1;
        for(int i=0; i<4; ++i) if(s[i+p]!=ZZ[i]) return 1;
        return 0;
    }
    else
    {
        if(p+2>n) return 1;
        for(int i=0; i<3; ++i) if(s[i+p]!=RR[i]) return 1;
        return 0;
    }
}
bool Check(int p)
{
    for(int k=0; k<4; ++k)
    {
        for(int i=0; i<5; ++i)
            if(i==4) return 0;
            else if(s[p+i]!=ban[k][i]) break;
    }
    return 1;
}

int main()
{
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);

    scanf("%s",s+1), n=strlen(s+1);
    f[1][0]=1, f[2][0]=2, f[3][0]=4;
    if(Diff(1,'z')) f[4][0]=8, f[4][1]=0;
    else f[4][0]=7, f[4][1]=1;
    for(int i=5; i<=n; ++i)
    {
        f[i][0]=f[i-1][0]+f[i-1][1]+f[i-2][0]+f[i-2][1]+f[i-3][0];
        if(Diff(i-2,'r')) f[i][0]+=f[i-3][1];
        if(Check(i-3)){
            if(Diff(i-3,'z')) f[i][0]+=f[i-4][0]+f[i-4][1];
            else f[i][1]+=f[i-4][0]+f[i-4][1];
        }
        f[i][0]%=mod, f[i][1]%=mod;
    }
    printf("%d\n",(int)((f[n][0]+f[n][1])%mod));

    return 0;
}

C 并行计算(贪心)

题目链接

交换律对应到树上就是可以交换某个点的左右儿子,结合律就是相同的运算符可以进行左旋右旋。
也就是由一个相同运算符组成的连通块内,可以任意安排顺序。
计算同一连通块所需要的最少合并时间,可以每次合并两个最小值\(x,y\),合并后为\(\max\{x,y\}+cost\),加入堆。
复杂度\(O(n\log n)\)

//368ms 45468kb
#include <queue>
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define MAXIN 300000
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=1e6+5;

int n,P,Q,fa[N],son[N][2];
char opt[N],IN[MAXIN],*SS=IN,*TT=IN;
std::priority_queue<int,std::vector<int>,std::greater<int> > q[N];

inline int read()
{
    int now=0;register char c=gc();
    for(;!isdigit(c);c=gc());
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now;
}
int DFS(int x,int anc)
{
    if(x>=n) return 0;
    for(int i=0; i<2; ++i)
    {
        int v=son[x][i];
        if(v>=n) q[anc].push(0);
        else if(opt[x]==opt[v]) DFS(v,anc);
        else q[anc].push(DFS(v,v));
    }
    if(x==anc)
    {
        int cost=opt[x]=='+'?P:Q;
        while(q[x].size()>1)
            q[x].pop(), q[x].push(q[x].top()+cost), q[x].pop();
        return q[x].top();
    }
    return 0;
}

int main()
{
    n=read(),P=read(),Q=read();
    register char c=gc(); for(;c!='+'&&c!='*';c=gc());
    opt[1]=c; for(int i=2; i<n; ++i) opt[i]=gc();
    for(int i=1,l=2*n-2,u,v; i<=l; ++i)
        u=read(), fa[v=read()]=u, son[u][son[u][0]>0]=v;
    for(int i=1; i<n; ++i) if(!fa[i]) {printf("%d\n",DFS(i,i)); break;}

    return 0;
}

D

题目链接

考试代码

C

#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=1e6+5;

int n,Ans,tot,pw[35],At,Mt,tm[3],Enum,H[N],fa[N],son[N][2],val[N],opt[N];

inline int read()
{
    int now=0,f=1;register char c=gc();
    for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now*f;
}
void DFS(int x,int &res,int cost)
{
    if(!res) return;
    if(!son[x][0]) val[x]=cost, --res;
    else DFS(son[x][0],res,cost);
    if(!son[x][1]) --res;
    else DFS(son[x][1],res,cost);
    val[x]=std::max(val[son[x][0]],val[son[x][1]])+cost;
}
void Sub1(int c)
{
    static int q[N];

    int h=0,t=1,now=1,res=n; q[1]=1;
    while(h<=t)
    {
        int x=q[++h];
        if(res) q[++t]=++now, son[x][0]=now, --res;
        if(res) q[++t]=++now, son[x][1]=now, --res;
    }
    res=tot-n, DFS(1,res,tm[c]), printf("%d\n",val[1]);
}

int main()
{
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);

//  pw[0]=1;
//  for(int i=1; i<30; ++i) pw[i]=pw[i-1]<<1;

    n=read()-1,tm[0]=read(),tm[1]=read(),tot=2*n+1;
    register char c=gc(); for(; c!='+'&&c!='*'; c=gc());
    opt[1]=c=='+'?0:1;
    for(int i=2; i<=n; ++i) opt[i]=gc()=='+'?0:1;

    bool f0=0,f1=0;
    for(int i=1; i<=n; ++i) if(!opt[i]) {f0=1; break;}
    for(int i=1; i<=n; ++i) if(opt[i]) {f1=1; break;}
    if(!f0) {Sub1(1); return 0;}
    else if(!f1) {Sub1(0); return 0;}

//  for(int i=1,u,v; i<=n<<1; ++i)
//  {
//      u=read(), fa[v=read()]=u;
//      if(!son[u][0]) son[u][0]=v;
//      else son[u][1]=v;
//  }
//  int root=1;
//  for(int i=1; i<=n; ++i) if(!fa[i]) {root=i; break;}

    return 0;
}

D

#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define MAXIN 300000
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=55;

int n,m,A[N],V[N],got[N],Ans;
char IN[MAXIN],*SS=IN,*TT=IN;

inline int read()
{
    int now=0;register char c=gc();
    for(;!isdigit(c);c=gc());
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now;
}
void DFS(int x)
{
    if(x>n)
    {
        for(int i=1; i<=n; ++i) got[i]=0;
        for(int t=m; t; --t)
        {
            int mx=V[1]/(got[1]+1),p=1;
            for(int i=2; i<=n; ++i)
                if(V[i]/(got[i]+1)>mx) mx=V[i]/(got[i]+1), p=i;
            ++got[p];
        }
        Ans=std::max(Ans,got[1]);
    }
    else if(x!=n) V[x]+=A[x], DFS(x+1), V[x]-=A[x], V[x+1]+=A[x], DFS(x+1), V[x+1]-=A[x];
    else V[n]+=A[x], DFS(x+1), V[n]-=A[x], V[1]+=A[x], DFS(x+1), V[1]-=A[x];
}

int main()
{
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    srand(20180921);

    n=read(),m=read();
    for(int i=1; i<=n; ++i) V[i]=read();
    for(int i=1; i<=n; ++i) A[i]=read();
    if(n<=25) DFS(1), printf("%d\n",Ans);
    else printf("%d\n",m);

    return 0;
}

9.21 正睿普及2

标签:gre   ++   连通   read   clu   bool   ESS   cst   最小   

原文地址:https://www.cnblogs.com/SovietPower/p/9703771.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!