HDU 6313 (数论构造,完全剩余系的性质)

题意:
求一个小于等于2000*2000的01方阵,1的数量不小于85000,满足矩阵中没有一个长方形的四个点都是1。

思路:
题目可以理解为,没有两列在同样的两行有1。
参考杜教的构造方法,写一下自己的理解。
对于一行5*5的方针,
+0:10000 10000 10000 10000 10000
+1:10000 01000 00100 00010 00001
+2:10000 00100 00001 01000 00010
+3:10000 00010 01000 00001 00100
+4:10000 00001 00010 00100 01000
    (1)   (2)   (3)   (4)   (5)
(1)中1全在第一列,那么后面的(2)(3)(4)(5)中都不能有一列存在两个1。
联想到完系的概念,一个质数p,p的完系{0,1,2...p-1}乘上任意一个gcd(x,p)==1的x,可以构成另一个完系。
我们把完系中的每个数理解成1的列数,x取[1,2...p-1],恰好对应了(2)(3)(4)(5)四个小方阵的1的列数。
例如(2)对应的完系是{0,1,2,3,4},对应x为1,(3)对应的完系是{2,4,1,3,0},对应x为2,这里把0所在的那一行移到第0行,就是上面的构造。

代码:

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <cctype>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <map>
#include <list>
#include <set>
#include <stack>
#include <queue>
#include <string>
#include <sstream>
#define pb push_back
#define X first
#define Y second
#define lch (o<<1)
#define rch (o<<1|1)
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define pii pair<int,int>
#define qclear(a) while(!a.empty())a.pop();
#define lowbit(x) (x&-x)
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define mst(a,b) memset(a,b,sizeof(a))
#define cout3(x,y,z) cout<<x<<" "<<y<<" "<<z<<endl
#define cout2(x,y) cout<<x<<" "<<y<<endl
#define cout1(x) cout<<x<<endl
#define O2 #pragma GCC optimize(2)
#define IOS std::ios::sync_with_stdio(false)
#define SRAND srand((unsigned int)(time(0)))
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
using namespace std;
const double PI=acos(-1.0);
const int INF=0x3f3f3f3f;
const ll mod=1e9+7;
const double eps=1e-8;
const int maxn=100005;
const int maxm=500005;

bool maps[3005][3005];
void solve() {
    int p=47;
    mst(maps,0);
    for(int i=0;i<p;i++){
        for(int j=0;j<p;j++){
            for(int k=0;k<p;k++){
                maps[i*p+j][k*p+(j*k+i)%p]=1;
            }
        }
    }
    printf("2000\n");
    for(int i=0;i<2000;i++){
        for(int j=0;j<2000;j++){
            printf("%d",maps[i][j]);
        }
        printf("\n");
    }
    return ;
}
int main() {
#ifdef LOCAL
    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
#else
    //    freopen("","r",stdin);
    //    freopen("","w",stdout);
#endif
    solve();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_38378637/article/details/81367904