HDU 6313 Hack It(数论构造)

题目链接

Hack It

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 721    Accepted Submission(s): 236
Special Judge

 

Problem Description

Tonyfang is a clever student. The teacher is teaching he and other students "bao'sou".
The teacher drew an n*n matrix with zero or one filled in every grid, he wanted to judge if there is a rectangle with 1 filled in each of 4 corners.
He wrote the following pseudocode and claim it runs in O(n2):

let count be a 2d array filled with 0s
iterate through all 1s in the matrix:
  suppose this 1 lies in grid(x,y)
  iterate every row r:
    if grid(r,y)=1:
      ++count[min(r,x)][max(r,x)]
      if count[min(r,x)][max(r,x)]>1:
        claim there is a rectangle satisfying the condition
claim there isn't any rectangle satisfying the condition



As a clever student, Tonyfang found the complexity is obviously wrong. But he is too lazy to generate datas, so now it's your turn.
Please hack the above code with an n*n matrix filled with zero or one without any rectangle with 1 filled in all 4 corners.
Your constructed matrix should satisfy 1≤n≤2000 and number of 1s not less than 85000.

Input

Nothing.

Output

The first line should be one positive integer n where 1≤n≤2000.

n lines following, each line contains only a string of length n consisted of zero and one.

Sample Input

(nothing here)

Sample Output

3

010

000

000

(obviously it's not a correct output, it's just used for showing output format)

题意:

让你构造一个矩阵使得里面不存在四个顶点都为1的矩形,并且矩阵里面1的个数要>=85000

解析:

看了大佬的构造.....

p=5

我们可以先从一个25*25的矩阵开始构造
10000 01000 00100 00010 00001
10000 00100 00001 01000 00010
10000 00010 01000 00001 00100
10000 00001 00010 00100 01000
10000 10000 10000 10000 10000
01000 00100 00010 00001 10000
01000 00010 10000 00100 00001
01000 00001 00100 10000 00010
01000 10000 00001 00010 00100
01000 01000 01000 01000 01000

...........................

观察上面的矩阵可以发现规律是

假设行数为x(x=1...25),列数y(y=1....25)

单论一行来说,总共只有5个1,可以分成5组,每组一个1

每一组的1的位置=((前一组1的位置k+x%p)-1)%p+1

那么我们只要知道每一行第一个位置在哪里就可以构造出来了。

这样第一列1的位置其实就是(x-1/p)

那么这样我们就可以构造出来一个满足上述条件的矩阵了。

但是这个25*25的矩阵只能满足n<=25的情况,一旦n>=25

那么就有可能出现重复的矩阵(以这个25*25为单元重复),两个重复的矩阵找对应的4个位置就可以构成一个矩形了

所以我们需要重新找一个质数p,使得p*p>=2000,那么可以很容易得到p=47

反正只要懂上面那个思想来构造就可以了,怎么写都看个人的习惯了。

 

#include <cstdio>
#include <cstring>

const int MAXN = 2001;
int mp[MAXN][MAXN];

int main()
{
    int n;
    int p=47;
    n=2000;
    for(int i=0;i<(n/(p*p)+(n%(p*p)?1:0));i++)
        for(int j=0;j<(n/(p*p)+(n%(p*p)?1:0));j++)
            for(int x=1;x<=(p*p)&&(i*(p*p)+x)<=n;x++)
                //for(int y=1;y<=p*p&&(j*(p*p)+y+(((y/p)*x)%p))<=n;y+=p)
                for(int y=0;y<p&&(j*(p*p)+y*p+((((x-1)/p+1+(((x-1)%p+1)*y%p))-1)%p+1))<=n;y+=1)
                {
                    mp[i*(p*p)+x][j*(p*p)+y*p+((((x-1)/p+1+(((x-1)%p+1)*y%p))-1)%p+1)]=1;
                }
    printf("%d\n",n);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            /*if(j%p==0) printf("%d ",mp[i][j]);
            else */printf("%d",mp[i][j]);
        }
        printf("\n");
    }
    return 0;

}

猜你喜欢

转载自blog.csdn.net/qq_37025443/article/details/81221008