2018 Multi-University Training Contest 2 E( Hack It)

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)

题意:要求构造一个n*n的矩阵,要求不存在一个子矩阵四个角都为1,矩阵的大小1<=n<=2000,矩阵中1的个数大于等于85000。

来自:http://www.cnblogs.com/shutdown113/p/9371135.html

n=3,1的位置在j上依次+0,1,2,3……(不知道该怎么证明)

 

对于上图,我们首先看一下,上面的矩阵是怎么构造出来的。

  1.首先对于第i块,第一列1的位置为第i个。

  2.对于第i块,我们也可以看成有n个小块,对于第i块中的第j小块(j>1),它的第k行中1的位置是由前一小块中1的位置+(k-1)得到,也就是说由第一小块中1的位置+(k-1)*(j-1)。

  因为矩阵最大为2000,所以我们构造矩阵的大小sz就取2000,为了构造时不会重复,所以n采用质数,最接近sqrt(sz)=sqrt(2000)的质数为47.

int main()
{
//    freopen("in.txt","r",stdin);
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            for(int k=0;k<n;k++){
                //i*n+j:第i+1块第j+1行
                //k*n:第k+1小块
                //(j*k+i)%n:第(j*k+i)%n列
                a[i*n+j][k*n+(j*k+i)%n]=1;
            }
        }
    }
    printf("%d\n",sz);
    for(int i=0;i<sz;i++){
        for(int j=0;j<sz;j++){
            printf("%d",a[i][j]);
        }
        printf("\n");
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值