zoukankan      html  css  js  c++  java
  • hdu 6952 / 2021“MINIEYE杯”中国大学生算法设计超级联赛(1) 1003 Puzzle loop (高斯消元解异或方程组)

    https://acm.hdu.edu.cn/showproblem.php?pid=6952

    题意:

    n条横线m条竖线构成(n-1)*(m-1)的网格图,现在要求在图上沿线画若干个不相交圈,圈与圈之间可以共享点但不能共享线。

    某些格子上有一个数0或者1,1表示这个格子周围4条线有奇数条属于画的圈,0表示偶数条。

    难点在于如何转化画圈问题

    画不相交的圈转化为n*m个交点周围4条线有偶数条属于画的圈

    把格子的每条短线看作1个变量

    结合0和1的要求构建异或方程组

    #include<bits/stdc++.h>
    
    using namespace std;
    
    #define N 21
    
    bitset<N*N*2>b[N*N*2];
    
    int n,m;
    
    int idh[N][N],idl[N][N];
    
    char s[N][N];
    
    const int mod=998244353;
    
    long long gauss()
    {
        int j,row=0;
        for(int i=0;i<m;++i)
        {
            j=row;
            while(j<n && !b[j][i]) ++j;
            if(j==n) continue;
            swap(b[row],b[j]);
            for(int k=row+1;k<n;++k)
                if(b[k][i]) b[k]^=b[row];
            ++row;
        }
        for(int i=row;i<n;++i) 
            if(b[i].test(m)) return 0; 
        int ans=1;
        for(int i=1;i<=m-row;++i) ans=1ll*ans*2%mod;
        return ans;
    }
    
    int main()
    {
    //    freopen("1.txt","w",stdout);
        int T,a,e;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&a,&e);
            m=0;
            for(int i=1;i<=a;++i)
                for(int j=1;j<e;++j)
                    idh[i][j]=m++;
            for(int i=1;i<=e;++i)
                for(int j=1;j<a;++j)
                    idl[i][j]=m++;
            n=0;
            for(int i=1;i<=a;++i)
                for(int j=1;j<=e;++j)
                {
                    if(j>1) b[n].set(idh[i][j-1]);
                    if(j<e) b[n].set(idh[i][j]);
                    if(i>1) b[n].set(idl[j][i-1]);
                    if(i<a) b[n].set(idl[j][i]);
                    ++n;
                //    printf("%d %d %d %d
    ",idh[i][j-1],idh[i][j],idl[j][i-1],idl[j][i]);
                }
            for(int i=1;i<a;++i) scanf("%s",s[i]+1);
            for(int i=1;i<a;++i)
                for(int j=1;j<e;++j)
                    if(s[i][j]!='.')
                    {
                        b[n].set(idh[i][j]);
                        b[n].set(idh[i+1][j]);
                        b[n].set(idl[j][i]);
                        b[n].set(idl[j+1][i]);
                //        printf("%d %d %d %d
    ",idh[i][j],idh[i+1][j],idl[j][i],idl[j+1][i]);            
                        if(s[i][j]=='1') b[n].set(m);
                        ++n;
                    }
            printf("%d
    ",gauss());
            for(int i=0;i<n;++i) b[i].reset();
        }
    }
    作者:xxy
    本文版权归作者和博客园共有,转载请用链接,请勿原文转载,Thanks♪(・ω・)ノ。
  • 相关阅读:
    sqlserver tips
    mysql tips
    小知识点集锦
    设计模式
    将微博或者qq空间的说说同步至博客园 wcf+js(ajax)跨域请求(1)
    WCF服务寄宿IIS与Windows服务
    C# 基础小知识之yield 关键字
    WPF命令绑定 自定义命令
    KnockOut 绑定之foreach绑定(mvc+knockout)
    P5019 铺设道路
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/15085240.html
Copyright © 2011-2022 走看看