• 9.3题解


    T1

    大家考场上都想到了暴搜,并且暴搜可以过,但是为什么还是有一大半的人$WA0$了呢,因为这题细节巨多,考场上我调了到快9点,才过了大样例,结果还是逃脱不了$WA0$的命运,我太难了

    其实思路上没有什么,你就枚举循环节的长度,把后面位置上有数字的对回来,看能不能合法就行了,记得疯狂调试

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<vector>
      6 #define inf 2139062143
      7 #define maxm 10010
      8 #define maxp 100100
      9 using namespace std;
     10 struct node{
     11     int p,x;
     12 }a[maxm];
     13 int t,c,m,js,tail,len,pd;
     14 int b[maxp],lon[5],ma[5],st[5],mi[5],stt[5];
     15 vector <int> chan;
     16 bool cmp(const node &a,const node &b)
     17 {
     18     return a.p<b.p;
     19 }
     20 int main()
     21 {
     22 //    freopen("1.in","r",stdin);
     23 //    freopen("W.out","w",stdout);
     24     scanf("%d%d",&t,&c);
     25     while(t--)
     26     {
     27         scanf("%d",&m);  js=0;  len=c;  pd=0;
     28         memset(b,-1,sizeof(b));  memset(lon,0,sizeof(lon));
     29         memset(ma,-1,sizeof(ma));  memset(st,-1,sizeof(st));
     30         memset(mi,0x7f,sizeof(mi));  memset(stt,0x7f,sizeof(stt));
     31         for(int i=1;i<=m;++i)
     32         {
     33             int pp,xx;  scanf("%d%d",&pp,&xx);
     34             if(b[pp-1]==-1)  {b[pp-1]=xx;  a[++js].p=pp-1;  a[js].x=xx;}
     35         }
     36         if(c==1)  {printf("1
    ");  continue;}
     37         sort(a+1,a+js+1,cmp);  tail=a[js].p+c;
     38         for(int i=1;i<=js;++i)
     39             if(a[i].x<a[i-1].x)  {tail=a[i].p;  break;}
     40         for(int i=0;i<len;++i)
     41             if(b[i]!=-1)  {st[b[i]]=i;  stt[b[i]]=min(stt[b[i]],i);}
     42         while(len<=tail)
     43         {
     44             if(b[len-1]!=-1)
     45                 {st[b[len-1]]=len-1;  stt[b[len-1]]=min(stt[b[len-1]],len-1);}
     46             for(int i=0;i<c;++i)  {mi[i]=stt[i];  ma[i]=st[i];}
     47             mi[0]=0;  mi[c-1]=min(len-1,mi[c-1]);  ma[c-1]=len-1;  chan.clear();
     48             int flag=0;
     49             for(int i=1;i<=js;++i)
     50             {
     51                 int ls=a[i].p%len;
     52                 if(b[ls]!=a[i].x)
     53                 {
     54                     if(b[ls]==-1)
     55                     {
     56                         if(a[i].x!=0&&ls<=ma[a[i].x-1]&&ma[a[i].x-1]!=-1)
     57                             {flag=1;  break;}
     58                         if(ls>mi[a[i].x+1])  {flag=1;  break;}
     59                         b[ls]=a[i].x;
     60                         chan.push_back(ls);
     61                         ma[a[i].x]=max(ma[a[i].x],ls);
     62                         mi[a[i].x]=min(mi[a[i].x],ls);
     63                     }
     64                     else  {flag=1;  break;}
     65                 }
     66             }
     67             if(flag)
     68             {
     69                 for(int i=0;i<chan.size();++i)  b[chan[i]]=-1;
     70                 len++;  continue;
     71             }
     72             else
     73             {
     74                 for(int i=0;i<c;++i)
     75                 {
     76                     if(ma[i]==-1)
     77                     {
     78                         if(i==0)  {ma[i]=0;  mi[i]=0;}
     79                         else
     80                         {
     81                             if(ma[i-1]+1!=mi[i+1])  {ma[i]=ma[i-1]+1;  mi[i]=ma[i];}
     82                             else  {flag=1;  break;}
     83                         }
     84                     }
     85                     if(mi[i]-ma[i-1]<=0&&i!=0)  {flag=1;  break;}
     86                     if(mi[i+1]-ma[i]==0&&i!=c-1)  {flag=1;  break;}
     87                 }
     88                 if(flag)
     89                 {
     90                     for(int i=0;i<chan.size();++i)  b[chan[i]]=-1;
     91                     len++;  continue;
     92                 }
     93                 lon[0]=ma[0]+1;
     94                 for(int i=1;i<c;++i)  lon[i]=ma[i]-ma[i-1];
     95                 pd=1;  break;
     96             }
     97         }
     98         if(!pd)  {printf("NO
    ");  continue;}
     99         for(int i=0;i<c;++i)  printf("%d ",lon[i]);
    100         puts("");
    101     }
    102     return 0;
    103 }
    调试过程中hack掉无数AC代码的来之不易的代码

    T2

    是个非常zz的区间dp,我在考场上却没有想出来,暴搜还调了很久

    如果dp转移的话,我们设$dp[i][j]$代表在$i$到$j$的区间中最多能得到的蛋糕大小。我们考虑怎么由$dp[i][j]$传到其他状态

    首先对于这种成环的问题,很经典的一种处理方式就是延长一倍变成序列上的问题,对于转移,我们分为两种情况

    1.卓司君取到蛋糕,那就是$i-1$和$j+1$都可以转移到,不出$2n$序列即可

    2.雨咲(xiao四声)酱取到蛋糕,在保证$i-1$和$j+1$合法的情况下,选一个大的转移就可以了

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #define int long long
     5 #define maxn 3010
     6 using namespace std;
     7 int n,ans;
     8 int a[maxn*2];
     9 int dp[maxn*2][maxn*2];
    10 main()
    11 {
    12     scanf("%lld",&n);
    13     for(int i=1;i<=n;++i)  scanf("%lld",&a[i]);
    14     a[0]=a[n];
    15     for(int i=1;i<=n;++i)  a[i+n]=a[i];
    16     for(int i=1;i<=2*n;++i)  dp[1][i]=a[i];
    17     for(int i=1;i<n;++i)//上一个区间长度
    18     {
    19         for(int j=1;j<=2*n;++j)//上一个区间左端点
    20         {
    21             int k=i+j-1;//上一个区间右端点
    22             int l=j,r=k;
    23             if(r>2*n)  continue;
    24             int ls1=l-1,ls2=r+1;
    25             if(i%2)//上一个区间是奇数,不计算贡献的人选
    26             {
    27                 if(ls1<0||ls2>2*n)  continue;
    28                 int pos=0;
    29                 if(a[ls1]>a[ls2])  pos=ls1;
    30                 else  pos=ls2;
    31                 if(pos>=l&&pos<=r)  continue;
    32                 if(pos<0||pos>2*n)  continue;
    33                 int ls=min(pos,l);
    34                 dp[i+1][ls]=max(dp[i+1][ls],dp[i][l]);
    35             }
    36             else//上一个区间是偶数,计算贡献的人选
    37             {
    38                 if(ls1<l||ls1>r)
    39                 {
    40                     if(ls1<0||ls1>2*n)  continue;
    41                     int ls=min(ls1,l);
    42                     dp[i+1][ls]=max(dp[i+1][ls],dp[i][l]+a[ls1]);
    43                 }
    44                 if(ls2<l||ls2>r)
    45                 {
    46                     if(ls2<0||ls2>2*n)  continue;
    47                     int ls=min(ls2,l);
    48                     dp[i+1][ls]=max(dp[i+1][ls],dp[i][l]+a[ls2]);
    49                 }
    50             }
    51         }
    52     }
    53     for(int i=1;i<=2*n;++i)  ans=max(ans,dp[n][i]);
    54     printf("%lld
    ",ans);
    55     return 0;
    56 }
    View Code

    T3

    说实话一开时没看懂题,说实话我最后抄的题解,觉得题解说的还可以,所以贴个题解,放个代码就跑了,我着急去水题

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<cmath>
      5 #include<queue>
      6 #define int long long
      7 #define bh(i,j)  ((i-1)*y+j)
      8 #define maxn 6001000
      9 #define maxm 6001000
     10 using namespace std;
     11 struct node{
     12     int pos,len;
     13     bool operator <(const node &a)const
     14     {
     15         return len>a.len;
     16     }
     17 };
     18 struct NODE{
     19     int h,z;
     20 };
     21 int x,y,a,b,c,n,ans,js,tot;
     22 int xx[maxn],yy[maxn];
     23 int head[maxn],to[maxm],xia[maxm],w[maxm];
     24 int pd[maxn],dis[maxn];
     25 priority_queue <node> s;
     26 queue <NODE> dl;
     27 void add(int x,int y,int z)
     28 {
     29     to[++js]=y;  xia[js]=head[x];  w[js]=z;  head[x]=js;
     30 }
     31 main()
     32 {
     33     scanf("%lld%lld%lld%lld%lld%lld",&x,&y,&a,&b,&c,&n);  x++;  y++;  tot=x*y;
     34     for(int i=1;i<=n;++i)  {scanf("%lld%lld",&xx[i],&yy[i]);  xx[i]++;  yy[i]++;}
     35     memset(dis,0x7f,sizeof(dis));
     36     for(int i=1;i<=n;++i)
     37     {
     38         int ls=bh(xx[i],yy[i]);  dis[ls]=0;
     39         dl.push((NODE){xx[i],yy[i]});
     40     }
     41     while(dl.size())
     42     {
     43         NODE ls=dl.front();  dl.pop();
     44         int ls1=ls.h,ls2=ls.z;
     45         if(ls2-1>=1&&dis[bh(ls1,ls2-1)]>dis[bh(ls1,ls2)]+1)
     46         {
     47             dis[bh(ls1,ls2-1)]=dis[bh(ls1,ls2)]+1;
     48             dl.push((NODE){ls1,ls2-1});
     49         }
     50         if(ls2+1<=y&&dis[bh(ls1,ls2+1)]>dis[bh(ls1,ls2)]+1)
     51         {
     52             dis[bh(ls1,ls2+1)]=dis[bh(ls1,ls2)]+1;
     53             dl.push((NODE){ls1,ls2+1});
     54         }
     55         if(ls1-1>=1&&dis[bh(ls1-1,ls2)]>dis[bh(ls1,ls2)]+1)
     56         {
     57             dis[bh(ls1-1,ls2)]=dis[bh(ls1,ls2)]+1;
     58             dl.push((NODE){ls1-1,ls2});
     59         }
     60         if(ls1+1<=x&&dis[bh(ls1+1,ls2)]>dis[bh(ls1,ls2)]+1)
     61         {
     62             dis[bh(ls1+1,ls2)]=dis[bh(ls1,ls2)]+1;
     63             dl.push((NODE){ls1+1,ls2});
     64         }
     65     }
     66     for(int i=1;i<=x;++i)
     67     {
     68         for(int j=1;j<=y;++j)
     69         {
     70             int ls1=bh(i,j),ls2=bh(i,j)+tot,ls3=bh(i,j)+2*tot;
     71             if(i-1>=1)  add(ls1,bh(i-1,j),a);
     72             if(i+1<=x)  add(ls1,bh(i+1,j),a);
     73             if(j-1>=1)  add(ls2,bh(i,j-1)+tot,a);
     74             if(j+1<=y)  add(ls2,bh(i,j+1)+tot,a);
     75             add(ls3,ls1,b);  add(ls3,ls2,b);
     76             add(ls1,ls3,dis[ls1]*c);  add(ls2,ls3,dis[ls1]*c);
     77             if(i-1>=1)  add(ls3,bh(i-1,j)+2*tot,c);
     78             if(i+1<=x)  add(ls3,bh(i+1,j)+2*tot,c);
     79             if(j-1>=1)  add(ls3,bh(i,j-1)+2*tot,c);
     80             if(j+1<=y)  add(ls3,bh(i,j+1)+2*tot,c);
     81         }
     82     }
     83     memset(dis,0x7f,sizeof(dis));
     84     int qd=bh(xx[1],yy[1])+2*tot;
     85     dis[qd]=0;  s.push((node){qd,dis[qd]});
     86     while(s.size())
     87     {
     88         int qd=s.top().pos;  s.pop();
     89         if(pd[qd])  continue;
     90         pd[qd]=1;
     91         for(int j=head[qd];j;j=xia[j])
     92         {
     93             int ls=to[j];
     94             if(dis[ls]>dis[qd]+w[j]&&(!pd[ls]))
     95             {
     96                 dis[ls]=dis[qd]+w[j];
     97                 s.push((node){ls,dis[ls]});
     98             }
     99         }
    100     }
    101     int zd=bh(xx[n],yy[n]);  ans=min(min(dis[zd],dis[zd+tot]),dis[zd+2*tot]);
    102     printf("%lld
    ",ans);
    103     return 0;
    104 }
    建边稍有一点点恶心

    感谢这道题,把我从错误的堆优化dj的板子里拉出来

  • 相关阅读:
    使用事务和SqlBulkCopy导入大批量数据
    Windows Server中禁止Administrator用户登录远程桌面
    SQL和C#的常用时间日期处理
    转:SQL Server数据库查询速度慢的原因
    火把节之夜,想发飙
    判断一个字符串是否为空
    .net中的using批注
    [转帖]删除鼠标右键的“用阿里旺旺打开此文件”的命令
    近凌晨12点却毫无睡意
    SQL SERVER取得汉字的拼音缩写
  • 原文地址:https://www.cnblogs.com/hzjuruo/p/11518799.html
Copyright © 2020-2023  润新知