2025多校冲刺省选模拟赛7

2025多校冲刺省选模拟赛7

T1 A. 三色卡(card) 0pts

  • 如果存在一个小矩形和大矩形的大小相同,此时另外两个矩形可以任意放,贡献是容易计算的。

  • 否则至少需要一个小矩形覆盖大矩形的两个角,通过交换长、宽钦定完全覆盖行的矩形比完全覆盖列的矩形的数量多。

  • 完全覆盖行的矩形数量为 1,2 时判掉无解后是容易统计贡献的。

  • 完全覆盖行的矩形数量为 3 时,直接在两边固定矩形后算另一个矩形可放置的极长区间会算重,不妨直接钦定不能顶到两边的边界,而顶到两边的边界单独提出来计算即可。

    点击查看代码
    const ll p=1000000007;
    ll h[5],w[5],a[5];
    ll solve(ll a,ll b,ll c,ll m)
    {
        ll flag=(max(w[a],w[b])+w[c]>=m);//顶到两边的边界
        if(w[a]+w[b]>=m)  return flag+m-w[c]-1;
        return flag+min(m-w[c],w[a]+1)-max(2ll,m-w[b]-w[c]+1)+1;
    }
    int main()
    {
    #define Isaac
    #ifdef Isaac
        freopen("card.in","r",stdin);
        freopen("card.out","w",stdout);
    #endif
        ll t,n,m,cnt,s1,s2,sum,minn,ans,i,j;
        cin>>t;
        for(j=1;j<=t;j++)
        {
            cin>>n>>m;
            cnt=s1=s2=sum=ans=0;  minn=0x7f7f7f7f;
            for(i=1;i<=3;i++)
            {
                cin>>h[i]>>w[i];  a[i]=i;
                cnt+=(h[i]==n&&w[i]==m);
                s1+=(h[i]==n);  s2+=(w[i]==m);
            }
            if(s2>s1)
            {
                swap(s1,s2);  swap(n,m);
                for(i=1;i<=3;i++)  swap(h[i],w[i]);
            }
            if(cnt==0)
            {
                if(s1==1)
                {
                    for(i=1;i<=3;i++)
                    {
                        if(h[i]==n)  s2=w[i];
                        else
                        {
                            sum+=h[i];
                            minn=min(minn,w[i]);
                        }
                    }
                    ans=(minn+s2>=m&&sum>=n)*4;
                }
                if(s1==2)
                {
                    ans=1;
                    for(i=1;i<=3;i++)
                    {
                        if(h[i]==n)  sum+=w[i];
                        else  ans=ans*(n-h[i]+1)%p*(m-w[i]+1)%p;
                    }
                    ans=(sum>=m)?2*ans:0;
                }
                if(s1==3)
                {
                    for(i=1;i<=3;i++)  sum+=w[i];
                    if(sum>=m)
                    {
                        do
                        {
                            ans=(ans+solve(a[1],a[2],a[3],m))%p;
                        }while(next_permutation(a+1,a+1+3));
                    }
                }
            }
            else
            {
                ans=1;
                for(i=1;i<=3;i++)  ans=ans*(n-h[i]+1)%p*(m-w[i]+1)%p;
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    

T2 B. 三项式(sequence) 20pts

  • 部分分

    • 20pts :爆搜。

      点击查看代码
      const ll p=1000000007;
      int ans=0;
      bool check(ll sum,int m)
      {
          int s1=0,s2=0;
          while(sum)
          {
              s1=(s1+sum%10)%m;
              s2=(s2+(sum%10)*(sum%10))%m;
              sum/=10;
          }
          return (s1==s2);
      }
      void dfs(int pos,int n,int m,ll sum,int l,int r)
      {
          if(pos==n+1)
          {
              if(check(sum,m)==true)  ans=(ans+1)%p;
              return;
          }
          for(int i=l;i<=r;i++)  dfs(pos+1,n,m,sum+i,l,r);
      }
      int main()
      {
      #define Isaac
      #ifdef Isaac
          freopen("sequencel.in","r",stdin);
          freopen("sequencel.out","w",stdout);
      #endif
          int n,m,l,r,lens,lene,i;
          cin>>n>>m>>l>>r;
          dfs(1,n,m,0,l,r);
          cout<<ans<<endl;
          return 0;
      }
      
  • 正解

T3 C. 三分图(graph) 0pts

  • 单看限制条件 3 太误导人了,等价于在限制 1 成立的条件下不存在两端属于同个部分的边。

  • 考虑扔到 DFS 树上考虑,从而天然满足第二条限制。

  • 将所有点按照深度的奇偶性划分成两个部分 V1,V2 ,然后进行分讨。

    • 若各部分点数均 2n ,选择符合第一条限制。由树上完美匹配经典结论贪心选择即可。
    • 否则,选择符合第三条限制。具体地,观察到叶子节点构成了独立集且足够多(根据 ||V1||V2||n 可知),将所有叶子节点扔到 V3 里即可。
    点击查看代码
    struct node
    {
        int nxt,to;
    }e[1000010];
    int head[1000010],dep[1000010],vis[1000010],son[1000010],ins[1000010],ans[1000010],num[2],cnt=0,n;
    void add(int u,int v)
    {
        cnt++;
        e[cnt].nxt=head[u];
        e[cnt].to=v;
        head[u]=cnt;
    }
    void dfs1(int x,int fa)
    {
        vis[x]=1;
        dep[x]=dep[fa]+1;
        num[dep[x]%2]++;
        ans[x]=dep[x]%2+1;
        for(int i=head[x];i!=0;i=e[i].nxt)
        {
            if(vis[e[i].to]==0)  
            {
                son[x]++;
                dfs1(e[i].to,x);
            }
        }
    }
    void dfs2(int x)
    {	
        int flag=0;
        vis[x]=1;
        for(int i=head[x];i!=0;i=e[i].nxt)
        {
            if(vis[e[i].to]==0)
            {
                dfs2(e[i].to);
                flag|=ins[e[i].to];
            }
        }
        if(flag==0&&num[dep[x]%2]-1>=n)
        {
            num[dep[x]%2]--;
            ans[x]=3;  ins[x]=1;
        }
    }
    int main()
    {
    #define Isaac
    #ifdef Isaac
        freopen("graph.in","r",stdin);
        freopen("graph.out","w",stdout);
    #endif
        int t,m,u,v,i,j;
        scanf("%d",&t);
        for(j=1;j<=t;j++)
        {
            scanf("%d%d",&n,&m);
            fill(e+1,e+1+cnt,(node){0,0});
            fill(head+1,head+1+3*n,0);
            fill(vis+1,vis+1+3*n,0);
            fill(son+1,son+1+3*n,0);
            fill(ins+1,ins+1+3*n,0);
            cnt=num[0]=num[1]=0;
            for(i=1;i<=m;i++)
            {
                scanf("%d%d",&u,&v);
                add(u,v);  add(v,u);
            }
            dfs1(1,0);
            if(max(num[0],num[1])<=2*n)
            {
                fill(vis+1,vis+1+3*n,0);
                dfs2(1);
            }
            else
            {
                for(i=1;i<=3*n;i++)  ans[i]=((son[i]==0)?3:ans[i]);
            }
            printf("YES\n");
            for(i=1;i<=3*n;i++)  printf("%d ",ans[i]);
            printf("\n");
        }
        return 0;
    }
    

总结

  • T1 分讨完后觉得太难写就直接摆烂去写左偏树了。而且当时对于三个同时覆盖行的情况算重了贡献,如果在场上估计也想不到解决方案。
  • T2 一开始读假题了,口胡了个 O((n+m1m1)) 的做法。

后记

  • T2 accoders NOI 和学校 OJ 的文件 IO 不一样。
  • T3checker.cpp 的并查集没有初始化导致循环输出 1,2,3 即可通过本题。
posted @   hzoi_Shadow  阅读(34)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
扩大
缩小
点击右上角即可分享
微信分享提示