题目描述
阿达马矩阵如下:
A0={1} A1={1 1} A2={1 1 1 1}
{1 0} {1 0 1 0}
{1 1 0 0}
{1 0 0 1}
可见,Ak是一个 2^k * 2^k 的矩阵。其中的规律自己去找{启示:把每一个矩阵分成四个的小矩阵来看}。
现在告诉你k的值,求第x行第y列的数字。
输入
输入有一行,三个数,分别是k(1≤k≤64),x,y(1≤x,y≤2^k)。
输出
输出有一个数,数值为0或1,表示第x行第y列的数字。
样例输入
2 2 2
样例输出
0
上代码,注释都在代码里
//该代码时间复杂度为O(k),可放心食用
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
/*
1.unsigned long long 是什么?
它是一种数据类型,存储范围0~(2^64)-1;
2. typedef 又是干嘛的?
typedef可以给一种类型取一个新的名字
比如 typedef int aaa;
你就可以在后文中用"aaa"代替"int"
*/
int ans,f=1;
int res[2][2]={{1,1},{1,0}};//存储基本单位
int turn(int x){//转换0和1
return x==0?1:0;
}
ull pows(int x){//求2的x次方
ull ans=1;
for(int i=1;i<=x;i++)ans*=2;
return ans;
}
void d(ull x,ull y,int k){
if(x<3&&y<3){
if(f==1)cout<<res[x-1][y-1];
else cout<<turn(res[x-1][y-1]);
return ;//不用我说了吧
}
else{
ull p=pows(k-1);//当范围长的一半
if(x>p&&y>p)f=-f;//判断象限,若在第四象限中则反一下
if(x>p)x-=p;//减一个一半其实情况是一样的,不懂的话可以手动模拟一下.
if(y>p)y-=p;//同上
d(x,y,k-1);
}
}
int main(){
ull k,x,y;
cin>>k>>x>>y;
d(x,y,k);
return 0;
}