zoukankan      html  css  js  c++  java
  • Codeforces CodeCraft-20

    小号冲黄失败...心塞塞_(:з」∠)_

    1316A - Grade Allocation

    (ans=min(m,sum_{i=1}^n a_i))

    #include<bits/stdc++.h>
    using namespace std;
    int T,n,m,a[1111];
    int main()
    {
        scanf("%d",&T);
        while(T--)
          {
          int s=0;
          scanf("%d%d",&n,&m);
          for(int i=1;i<=n;i++)
            scanf("%d",&a[i]),s=min(m,s+a[i]);
          printf("%d
    ",s);
          }
    }
    View Code

    1316B - String Modification

    可以试着找找规律,以下列出(n=4,5,6,7,8  k=4)时的结果

    (1234 ightarrow  4321)

    (12345 ightarrow  45123)

    (123456 ightarrow  456321)

    (1234567 ightarrow  4567123)

    (12345678 ightarrow  45678321)

    应该就能猜出结论了,枚举(k)即可

    #include<bits/stdc++.h>
    using namespace std;
    int T,n,ans;
    string s,mn;
    string rua(int k)
    {
        if(k==n)
          {
          string res=s;
          reverse(res.begin(),res.end());
          return res;
          }
        int t=n-k+1;
        if(t%2==0)
          {
          string res=s.substr(k-1,n-k+1);
          res+=s.substr(0,k-1);
          return res;
          }
        string res=s.substr(k-1,n-k+1);
        string tmp=s.substr(0,k-1);
        reverse(tmp.begin(),tmp.end());
        res=res+tmp;
        return res;
    }
    int main()
    {
        scanf("%d",&T);
        while(T--)
          {
          scanf("%d",&n);
          cin>>s;
          ans=1,mn=s;
          for(int i=2;i<=n;i++)
            if(rua(i)<mn)mn=rua(i),ans=i;
          cout<<mn<<endl<<ans<<endl;
          }
    }
    View Code

    1316C - Primitive Primes

    设(left { a_n ight })中第一个不被(p)整除的数为(a_i),(left { b_m ight })中第一个不被(p)整除的数为(b_j),则答案为(i+j)

    证明:考虑所有满足(0le x < n, 0 le y <m, x+y=i+j)的数对((x,y)),显然(x<i)和(y<j)这两个不等式至少有一个成立,故(a_x cdot b_y)必定为(p)的倍数。又由于(p)为质数,所以(a_i cdot b_j)一定不为(p)的倍数,结论成立

    #include<bits/stdc++.h>
    using namespace std;
    #define N 1000001
    int n,m,p,a[N],b[N],l,r;
    int main()
    {
        scanf("%d%d%d",&n,&m,&p);
        for(int i=0;i<n;i++)
          scanf("%d",&a[i]);
        for(int i=0;i<m;i++)
          scanf("%d",&b[i]);
        while(a[l]%p==0)l++;
        while(b[r]%p==0)r++;
        printf("%d
    ",l+r);
    }
    View Code

    1316D - Nash Matrix

    对所有(a[i][j]=(i,j))的点,设该点为'X',进行BFS,若周围有以该点为终点的点则加入队列,并将其指向上一个点

    对所有(a[i][j]=(-1,-1))的点,寻找一个与它相邻且同样为((-1,-1))的点,若有解则一定能找到。这时可以令这两个点互相可达(造成死循环),同样把这两个点加入队列,进行类似的BFS即可

    最后如果有未被赋值的点则无解

    #include<bits/stdc++.h>
    using namespace std;
    #define N 1010
    int n,x,y,a[N][N];
    int dx[4]={0,1,0,-1};
    int dy[4]={1,0,-1,0};
    char ans[N][N],f[4]={'L','U','R','D'};
    queue<int>q;
    int id(int x,int y){return (x+1)*N+y;}
    void rua(int x,int y)
    {
        if(ans[x][y]!='I')return;
        if(a[x][y]<0)
          for(int i=0;i<4;i++)
            {
            int nxtx=x+dx[i],nxty=y+dy[i];
            if(nxtx<1 || nxtx>n || nxty<1 || nxty>n)continue;
            if(a[nxtx][nxty]==a[x][y])
              {
              ans[nxtx][nxty]=f[i];
              ans[x][y]=f[(i+2)%4];
              q.push(id(x,y));
              q.push(id(nxtx,nxty));
              break;
              }
            }
        else ans[x][y]='X',q.push(id(x,y));
        while(!q.empty())
          {
          int cur=q.front();
          q.pop();
          x=cur/N-1,y=cur%N;
          for(int i=0;i<4;i++)
            {
            int nxtx=x+dx[i],nxty=y+dy[i];
            if(nxtx<1 || nxtx>n || nxty<1 || nxty>n)continue;
            if(a[nxtx][nxty]==a[x][y] && ans[nxtx][nxty]=='I')
              ans[nxtx][nxty]=f[i],q.push(id(nxtx,nxty));
            }
          }
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
          for(int j=1;j<=n;j++)
            {
            scanf("%d%d",&x,&y);
            a[i][j]=id(x,y);
            ans[i][j]='I';
            }
        for(int i=1;i<=n;i++)
          for(int j=1;j<=n;j++)
            if(a[i][j]==id(i,j) || a[i][j]<0)rua(i,j);
        for(int i=1;i<=n;i++)
          for(int j=1;j<=n;j++)
            if(ans[i][j]=='I')return printf("INVALID
    "),0;
        printf("VALID
    ");
        for(int i=1;i<=n;i++)
          {
          for(int j=1;j<=n;j++)
            printf("%c",ans[i][j]);
          printf("
    ");
          }
    }
    View Code

    1316E - Team Building

    首先对所有人按(a_i)降序排序,进行状压DP。设(f[i][bit])为前(i)个人,已经确定位置的状态为(bit)时的最优解,进行转移即可

    #include<bits/stdc++.h>
    using namespace std;
    #define N 100001
    #define LL long long
    LL n,p,k,f[N][128];
    struct rua
    {
        LL v,s[8];
        bool operator <(const rua &t)const{return v>t.v;}
    }a[N];
    int main()
    {
        scanf("%lld%lld%lld",&n,&p,&k);
        for(LL i=1;i<=n;i++)scanf("%lld",&a[i].v);
        for(LL i=1;i<=n;i++)
          for(LL j=0;j<p;j++)
            scanf("%lld",&a[i].s[j]);
        sort(a+1,a+n+1);
        for(LL b=0;b<(1<<p);b++)f[0][b]=-1e18;
        f[0][0]=0;
        for(LL i=1;i<=n;i++)
          for(LL b=0,cnt=0;b<(1<<p);b++,cnt=0)
            {
            f[i][b]=-1e18;
            for(LL k=0;k<p;k++)if((1ll<<k)&b)
              cnt++,f[i][b]=max(f[i][b],f[i-1][(1ll<<k)^b]+a[i].s[k]);
            f[i][b]=max(f[i][b],f[i-1][b]+(i<=cnt+k?a[i].v:0));
            }
        printf("%lld
    ",f[n][(1<<p)-1]);
    }
    View Code

    1316F - Battalion Strength

    看了几份AC代码,大概知道了其中一种做法,先讲一下大致思路等白天起床再写_(:з」∠)_

    首先对(p_i)排序,先考虑不修改的时候答案是多少

    对于任意两对数(p_i, p_j, i<j),若这两个数相邻,则其产生的价值为(p_i cdot p_j),而能让这两个数相邻的子集数则为(2^{n-(j-i+1)}),其中(n-(j-i+1))表示把区间([i,j])掏空后的元素个数。这样我们可以得到(2^ncdot ans=sum_{i=1}^nsum_{j=i+1}^n p_icdot p_j cdot 2^{n-j+i-1}),稍微化简一下可以得到(2cdot ans=sum_{i=1}^nsum_{j=i+1}^n p_icdot p_j cdot 2^{-j+i}=sum_{i=1}^nsum_{j=i+1}^n p_icdot 2^i cdot p_j cdot 2^{-j}),这个时候我们就可以用线段树来求解,合并的式子为(ans=l_{ans}+r_{ans}+l_{s1}cdot r_{s2}),(s1,s2)分别表示(p_i)乘上(2^i)和(2^{-i})的和

    对于有修改的情况,可以考虑离线处理

    得到所有的修改的信息后,对(p_i)和修改的值混在一起进行排序,开一个(n+q)大小的线段树,并额外记录区间内有多少个位置有值。每次修改就相当于把其中一个位置变为(0),另外一个空位变成想要修改的值即可,这样仍然能够保证内部的值是升序排列的,把之前的式子稍作改动即可(额外考虑区间内非空位的个数带来的指数影响)

    upd:过了_(:з」∠)_具体做法稍微有点偏差,详细题解随后更

    #include<bits/stdc++.h>
    using namespace std;
    #define N 600001
    #define MOD 1000000007
    int n,m,p[N],q[N],I[N],v;
    struct pi
    {
        int v,id;
        void read(int i){scanf("%d",&v),id=i;}
        bool operator <(const pi &t)const{return v<t.v;}
    }a[N];
    struct rua
    {
        int c,ans,sl,sr;
    }t[N<<2];
    void change(int x,int i,int l,int r,int o)
    {
        if(l==r)
          {
          t[i].c=o;
          t[i].ans=t[i].sl=t[i].sr=0;
          if(o)t[i].sl=t[i].sr=1ll*I[1]*a[x].v%MOD;
          return;
          }
        int mid=l+r>>1,ls=i*2,rs=ls+1;
        if(x<=mid)change(x,ls,l,mid,o);
        else change(x,rs,mid+1,r,o);
        t[i].c=t[ls].c+t[rs].c;
        t[i].sl=(1ll*t[ls].sl*I[t[rs].c]+t[rs].sl)%MOD;
        t[i].sr=(1ll*t[rs].sr*I[t[ls].c]+t[ls].sr)%MOD;
        t[i].ans=(t[ls].ans+t[rs].ans+1ll*t[ls].sl*t[rs].sr)%MOD;
    }
    int main()
    {
        I[0]=1,I[1]=(MOD+1)/2;
        for(int i=2;i<N;i++)
          I[i]=1ll*I[1]*I[i-1]%MOD;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
          a[i].read(i),p[i]=i;
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
          {
          scanf("%d",&q[i]);
          a[n+i].read(n+i);
          p[n+i]=n+i;
          }
        sort(a+1,a+n+m+1);
        for(int i=1;i<=n+m;i++)
          p[a[i].id]=i;
        for(int i=1;i<=n;i++)
          change(p[i],1,1,n+m,1);
        printf("%d
    ",t[1].ans);
        for(int i=1;i<=m;i++)
          {
          change(p[q[i]],1,1,n+m,0);
          change(p[n+i],1,1,n+m,1),p[q[i]]=p[n+i];
          printf("%d
    ",t[1].ans);
          }
    }
    View Code

     upd2[CodeCraft-20 (Div. 2)][Codeforces 1316F. Battalion Strength]

  • 相关阅读:
    Linux环境定时备份mysql数据库
    idea以DEBUG方式启动项目卡住,但是不报错
    Linux查看防火墙,开放端口
    element动态添加删除表格的行数
    触发器编写,执行插入或update分别执行不同sql
    vue数组判断数值,遍历,过滤
    将某文件夹下的文件压缩成zip
    转载:win10专业版取消自动更新
    IIS启动应用程序池报错"服务无法在此时接受控制信息
    IIS7 设置网站默认主页(首页)
  • 原文地址:https://www.cnblogs.com/DeaphetS/p/12418148.html
Copyright © 2011-2022 走看看