• NOIP2017赛前模拟(5):总结


    题目:

    1.刮刮卡

      已知n(n<=1000000)张刮刮卡按顺序排列,刮开可以获得B元现金和B个积分,购买刮刮卡需要A元,某人若按照顺序刮开的话··当B的总和小于A时便会停止刮卡(即花出去的钱多余赢得的钱),现在我们可以将前k张按原来的顺序放到后面去···问k取多少时这个人可以获得多少积分?

    2.矩阵

      给出一个n行m阵的矩阵(n,m<=100),问如果从中选出K个互不重叠的非空子矩阵使得子矩阵的和最大

    3.裁剪表格

      给出n行m列的矩阵··(n,m<=1000)和q(q<=10000)次操作··每次操作交换两个互不重合的子矩阵···输出最后的矩阵

    题解:

    1.最大子串和

      略

      代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #include<cctype>
    #include<string>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=2e6+5;
    inline int R()
    {
      char c;int f=0;
      for(c=getchar();c<'0'||c>'9';c=getchar());
      for(;c<='9'&&c>='0';c=getchar())  f=(f<<3)+(f<<1)+c-'0'; 
      return f;
    } 
    int num[N*2],a[N],b[N*2],n;
    int main()
    {
      //freopen("rock.in","r",stdin);
      //freopen("rock.out","w",stdout);
      n=R();int ans=0,sum1=0,maxx=0,sum2=0;
      for(int i=1;i<=n;i++)  b[i]=b[i+n]=R();
      for(int i=1;i<=n;i++)  a[i]=R(),num[i]=num[i+n]=b[i]-a[i];
      int Head=1;
      while(Head<=n)
      {
        if(num[Head]<0)  {Head++;continue;}
        int Tail=Head;sum1=0,sum2=0;
        while(Tail-Head+1<=n)
        {
          sum1+=num[Tail];
          sum2+=b[Tail];
          if(sum2>maxx) 
            maxx=sum2,ans=Head-1;
          if(Tail-Head+2<=n&&sum1+num[Tail+1]>=0)  
            Tail++;
          else break;
        }  
        Head=Tail+1;
      }
      cout<<ans<<endl;
      return 0;
    }

    2.dp

      用f[i][j][k]表示第一列取了前i个,第二列取了前j个且组成了k个子矩阵的最小值,具体转移方程看代码吧··

      md考试时忘记初始化-inf了····下次一定要注意··

      代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #include<cctype>
    #include<string>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=105;
    const int K=15;
    const long long inf=1e+18;
    int n,m,k,num[N],map[N][5];
    long long f1[N],sum[5][N],temp[N],f2[N][N][K];
    inline int R()
    {
      char c;int f=0,i=1;
      for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar());
      if(c=='-')  i=-1,c=getchar();
      for(;c<='9'&&c>='0';c=getchar())  f=(f<<3)+(f<<1)+c-'0';
      return f*i;
    }
    int main()
    {
      //freopen("matrix.in","r",stdin);
     // freopen("matrix.out","w",stdout);
      n=R(),m=R(),k=R();
      if(m==1)
      {
        for(int i=1;i<=n;i++)  num[i]=R();
        memset(f1,-10,sizeof(f1));
        f1[0]=0;
        for(int i=1;i<=k;i++)
        {  
          for(int j=i;j<=n;j++) 
          {
            if(j==i)  f1[j]=temp[j-1]+num[j];
            else f1[j]=max(f1[j-1]+num[j],temp[j-1]+num[j]);
          }
          for(int j=i;j<=n;j++)
          {
            if(j==i)  temp[j]=f1[j];
            else temp[j]=max(temp[j-1],f1[j]);
          }
        }
        long long ans=-inf;
        for(int i=k;i<=n;i++)  ans=max(ans,f1[i]);
        cout<<ans<<endl;
      }
      else
      {
        memset(f2,-10,sizeof(f2));
        long long tot=0;bool flag=true;
        for(int i=1;i<=n;i++)  
          for(int j=1;j<=2;j++)  
          {  
            map[i][j]=R();tot+=map[i][j];
            if(map[i][j]<0)  flag=false;
            sum[j][i]=sum[j][i-1]+map[i][j];
          }
        if(flag)  
        {
          cout<<tot<<endl;return 0;
        }
        for(int i=0;i<=n;i++)
          for(int j=0;j<=n;j++)  f2[i][j][0]=0;
        for(int i=1;i<=k;i++)
          for(int j=1;j<=n;j++)  //第一列 
            for(int l=1;l<=n;l++)  //第二列 
            { 
              f2[j][l][i]=max(f2[j-1][l][i],f2[j][l-1][i]);
              for(int p=0;p<j;p++) 
                f2[j][l][i]=max(f2[j][l][i],f2[p][l][i-1]+sum[1][j]-sum[1][p]);
              for(int p=0;p<l;p++)
                f2[j][l][i]=max(f2[j][l][i],f2[j][p][i-1]+sum[2][l]-sum[2][p]);
              if(l==j)
              for(int p=0;p<j;p++)
                f2[j][l][i]=max(f2[j][l][i],f2[p][p][i-1]+sum[2][l]-sum[2][p]+sum[1][j]-sum[1][p]);
            }
        cout<<f2[n][n][k]<<endl;
      }
      return 0;
    }

    3.链表

      看了题解后发现链表是一个神奇的东西··另外也发现register配上for循环的优化效果的显著···

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #include<cctype>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    const int N=1005;
    int n,m,q,pos[N][N],ri[N*N],down[N*N],val[N*N],tot;
    inline int R()
    {
      char c;int f=0;
      for(c=getchar();c<'0'||c>'9';c=getchar());
      for(;c<='9'&&c>='0';c=getchar())  f=(f<<3)+(f<<1)+c-'0';
      return f;
    }
    inline int find(int x,int y)
    {
      int t=pos[0][0];
      for(int i=1;i<=x;i++)  
        t=down[t]; 
      for(int i=1;i<=y;i++)
        t=ri[t];
      return t;
    }
    int main()
    {
      //freopen("a.in","r",stdin);
      n=R(),m=R(),q=R();
      for(register int i=1;i<=n;i++)
        for(register int j=1;j<=m;j++)   
          val[pos[i][j]=++tot]=R();
      for(register int i=0;i<=m+1;i++)
        pos[0][i]=++tot,pos[n+1][i]=++tot;
      for(register int i=1;i<=n;i++)
        pos[i][0]=++tot,pos[i][m+1]=tot;
      for(register int i=0;i<=n;i++)
        for(register int j=0;j<=m;j++)
        { 
          ri[pos[i][j]]=pos[i][j+1];
          down[pos[i][j]]=pos[i+1][j];
        }
      while(q--)
      {
        int r1=R(),c1=R(),r2=R(),c2=R(),h=R(),w=R();
        register int t1=find(r1-1,c1-1),t2=find(r2-1,c2-1),T1,T2,i;
        for(T1=t1,T2=t2,i=1;i<=h;i++)
          swap(ri[T1=down[T1]],ri[T2=down[T2]]);
        for(i=1;i<=w;i++)
          swap(down[T1=ri[T1]],down[T2=ri[T2]]);
        for(T1=t1,T2=t2,i=1;i<=w;i++)
          swap(down[T1=ri[T1]],down[T2=ri[T2]]);
        for(i=1;i<=h;i++) 
          swap(ri[T1=down[T1]],ri[T2=down[T2]]);
      }
      int p=pos[0][0];
      for(register int i=1;i<=n;i++)
      {
        p=down[p];
        for(register int j=1,t=p;j<=m;j++)
          cout<<val[t=ri[t]]<<" ";
        cout<<endl;
      }
      return 0;
    }
  • 相关阅读:
    使用没有初始化变量很危险
    openssl动态库编译
    数据库水平切分及问题
    用dpkg命令制作deb包方法总结
    centOS安装mysql---glibc方式
    RabbitMQ常用命令
    shell脚本报错:-bash: xxx: /bin/bash^M: bad interpreter: No such file or directory
    mysql主从复制实现数据库同步
    CentOS 7.0下使用yum安装MySQL
    RabbitMQ的远程Web管理与监控工具
  • 原文地址:https://www.cnblogs.com/AseanA/p/7700822.html
Copyright © 2020-2023  润新知