POJ 2961 Sylvester construction 哈达玛矩阵


Sylvester construction
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 1201 Accepted: 556

Description

A Hadamard matrix of order n is an n x n matrix containing only 1s and -1s, called H n, such that H nH n T = nI n where I n is the n x n identity matrix. An interesting property of Hadamard matrices is that they have the maximum possible determinant of any n x n matrix with elements in the range [-1, 1]. Hadamard matrices have applications in errorcorrecting codes and weighing design problems. 

The Sylvester construction is a way to create a Hadamard matrix of size 2n given H n. H 2n can be constructed as: 
 
for example: 
 
and so on. 

In this problem you are required to print a part of a Hadamard matrix constructed in the way described above.

Input

The first number in the input is the number of test cases to follow. For each test case there are five integers: n, x, y, w and h. n will be between 1 and 2 62 (inclusive) and will be a power of 2. x and y specify the upper left corner of the sub matrix to be printed, w and h specify the width and height respectively. Coordinates are zero based, so 0 ≤ x,y < n. You can assume that the sub matrix will fit entirely inside the whole matrix and that 0 < w,h ≤ 20. There will be no more than 1000 test cases.

Output

For each test case print the sub matrix followed by an empty line.

Sample Input

3
2 0 0 2 2
4 1 1 3 3
268435456 12345 67890 11 12

Sample Output

1 1
1 -1

-1 1 -1
1 -1 -1
-1 -1 1

1 -1 -1 1 1 -1 -1 1 1 -1 -1
-1 -1 1 1 -1 -1 1 1 -1 -1 1
1 1 1 -1 -1 -1 -1 1 1 1 1
-1 1 -1 -1 1 -1 1 1 -1 1 -1
1 -1 -1 -1 -1 1 1 1 1 -1 -1
-1 -1 1 -1 1 1 -1 1 -1 -1 1
-1 -1 -1 -1 -1 -1 -1 1 1 1 1
1 -1 1 -1 1 -1 1 1 -1 1 -1
-1 1 1 -1 -1 1 1 1 1 -1 -1
1 1 -1 -1 1 1 -1 1 -1 -1 1
-1 -1 -1 1 1 1 1 1 1 1 1
1 -1 1 1 -1 1 -1 1 -1 1 -1

Source



哈达玛(Hadamard)矩阵是由+1和-1元素构成的且满足Hn*Hn’=nI(这里Hn’为Hn的转置,I为单位方阵)n阶方阵。
本题要求打印构造出来的Hadamard矩阵的一部分。

//356K	16MS
#include<stdio.h>
int H[2][2]={{1,1},{1,-1}};
long long dfs(long long x,long long y)
{
    if(x<2&&y<2)return H[x][y];
    int i=0,j=0;
    if(x>=2)
    {
        i=1;
        while(i*2<=x)
            i*=2;
        x-=i;
    }
    if(y>=2)
    {
        j=1;
        while(j*2<=y)
            j*=2;
        y-=j;
    }
    if(i==j)return -dfs(x,y);//位于4区
    else if(i>j)return dfs(x,y+j);//位于3区
    else return dfs(x+i,y);//位于2区
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        long long n,x,y,w,h,i,j;
        scanf("%I64d%I64d%I64d%I64d%I64d",&n,&x,&y,&w,&h);
        for(i=y;i<y+h;i++)
        {
            for(j=x;j<x+w-1;j++)
                printf("%d ",dfs(i,j));
            printf("%d\n",dfs(i,j));
        }
        printf("\n");
    }
    return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值