https://vjudge.net/problem/CodeForces-1332D
题目大意:假设有一个
n
∗
m
n*m
n∗m的矩阵,初始位置在
(
1
,
1
)
(1,1)
(1,1),
s
c
o
r
e
1
=
a
11
score_1=a_{11}
score1=a11,每次只能向右或向下走,假设走到了位置
(
x
,
y
)
(x,y)
(x,y),那么分数变为
s
c
o
r
e
i
=
s
c
o
r
e
i
−
1
&
a
x
y
score_i=score_{i-1}\&a_{xy}
scorei=scorei−1&axy。可以找到一条从左上角到右小角的路径的分数最大,设其为
k
1
k_1
k1。同时给了一份伪代码,假设那份代码对当前矩阵的输出为
k
2
k_2
k2,要求
k
1
−
k
2
=
k
k_1-k_2=k
k1−k2=k。现在给你
k
k
k,让你输出构造出的这个矩阵。
思路:其实也是个水题,
2
∗
3
2*3
2∗3的矩阵就可以构造出解。
总体思路如上图所示,取得最大值的路径是红色部分,但是我们要让伪代码选择蓝色部分别的路径,不难想到以下方案:
A
11
&
A
12
&
A
22
&
A
23
=
k
A_{11}\&A_{12}\&A_{22}\&A_{23}=k
A11&A12&A22&A23=k
A
11
&
A
21
&
A
22
&
A
23
=
0
A_{11}\&A_{21}\&A_{22}\&A_{23}=0
A11&A21&A22&A23=0现在考虑怎么填数,首先让
A
12
=
A
23
=
k
A_{12}=A_{23}=k
A12=A23=k,那么必须满足
A
22
&
A
12
=
k
A_{22}\&A_{12}=k
A22&A12=k且
A
11
&
A
21
&
A
22
&
A
23
=
0
A_{11}\&A_{21}\&A_{22}\&A_{23}=0
A11&A21&A22&A23=0。令
t
m
p
=
c
e
i
l
(
l
o
g
2
(
k
+
1
)
)
tmp=ceil(log_2(k+1))
tmp=ceil(log2(k+1))。不妨设
b
=
2
t
m
p
b=2^{tmp}
b=2tmp,
a
=
b
+
k
a=b+k
a=b+k,显然有
a
&
b
&
a
=
b
>
k
&
a
&
k
=
k
a\&b\&a=b>k\&a\&k=k
a&b&a=b>k&a&k=k。那么矩阵就构造出来了。
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
int main()
{
int k;
scanf("%d",&k);
int v=ceil(log2(k+1));
int b=1<<v;
int a=b+k;
printf("2 3\n");
printf("%d %d %d\n",a,k,0);
printf("%d %d %d\n",b,a,k);
return 0;
}