前言
居然说T1是签到题,直接不会,T2构造简单多了。
太蒟蒻了。qwq
被同桌吊打中。qwq
T2
容易想到一种美丽的构造方法。
n=2时:
0 1
1 0
n=4时:
1 1 0 1
0 0 0 1
1 0 0 0
1 0 1 1
n=6时:
1 1 0 1 0 1
0 0 0 1 0 1
1 1 0 0 0 0
0 0 0 0 1 1
1 0 1 0 0 0
1 0 1 0 1 1
n=8时:
1 1 0 1 0 1 0 1
0 0 0 1 0 1 0 1
1 1 0 0 0 0 0 0
0 0 0 1 0 0 1 1
1 1 0 0 1 0 0 0
0 0 0 0 0 0 1 1
1 0 1 0 1 0 0 0
1 0 1 0 1 0 1 1
容易发现就是从外围用1 1绕一圈,然后再在里面的圈继续相同的方法绕。
对于每一圈,其1的个数为:
( n 2 − 1 ) × 4 × 2 = 4 n − 8 (\frac{n}{2}-1) \times 4\times 2 =4n-8 (2n−1)×4×2=4n−8
特别地,对于n=2的情况,1的个数为2。
对于放置1,就变得非常简单了,外围按照这种方法放即可,里面如果能放下,即n-6后大于等于2,由于是相同的,直接递归即可。
特别地,内围n=2时,放法为
1 0
0 1
我们统计1的个数就有2种方法了
可以每次递归时计算,但对于1e9的数据非常不友好,直接爆栈。
那么可以直接先算出了,用for循环,O(n/6)得到,或者推式子O(1)得到。
这里我使用的for循环。
由于输出较大,建议快输,putchar。
代码实现:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define re register
#define num ch-'0'
void get(int &res){
char ch;bool flag=0;
while(!isdigit(ch=getchar()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getchar());res=res*10+num);
(flag)&&(res=-res);
}
void print(int X)
{
if(X<0) {
X=~(X-1); putchar('-');}
if(X>9) print(X/10);
putchar(X%10+'0');
}
int n,cas;
int ans;
bool a[10005][