当时做的时候感觉快要搞出来了的 但是最后还是没有
向鱼骨一样错开,比如
111110 000001
100000 111111
111110 000001
100000 111111
111110 000001
首先这样能保证合并之后全图都是0 考虑如果该点强制是1 那么该点是0的矩阵就变成1就好 这个1可以和上一行或者下一行相连
这个构造属实巧妙 奇偶交错 这样保证在改变一个矩阵的情况下一定不会改变另一矩阵
点击查看代码
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int maxn=700;
char c[maxn][maxn];
char a[maxn][maxn];
char b[maxn][maxn];
int main()
{
int n,m;
cin>>n>>m;
char ch=getchar();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>c[i][j];
}
ch=getchar();
}
for(int i=1;i<=n;i++)
{
int ans=0;
for(int j=1;j<=m;j++)
{
if(i==1||i==n||j==1||j==m)
{
a[i][j]='1';
continue;
}
if(c[i][j]=='1')
{
ans++;
a[i][j]='1';
}
}
if(ans&&i%2==1)
{
for(int j=2;j<m;j++)
a[i][j]='1';
}
else
{
for(int j=2;j<m;j++)
if(a[i][j]!='1')
a[i][j]='0';
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(c[i][j]=='1')b[i][j]='1';
else if(a[i][j]=='1')b[i][j]='0';
else b[i][j]='1';
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cout<<a[i][j];
}
cout<<endl;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cout<<b[i][j];
}
cout<<endl;
}
}
题目大意:
给你k个方案数,让你构树
每个点有白色和黑色
并且如果树上有个点是黑色的那么它的子树也是黑色的
给出符合要求有k中方案的树
首先观察规律
一个点的方案数=(它所有的子树方案数的累乘+1)
然后如果是没有子树的点那么它的方案数就是2
一般构造就是分奇偶性的 !!!!!
如果是目前方案数是奇数
我们就拆成两个子树,方案数就变一半了
因为有一个子树是单独一个点,而该点的方案数就是2
对另一个子树再进行相同操作
如果目前方案数是偶数的
我们就让他连上一个点,让他变成奇数,这时候方案数-1
(因为子树就一个嘛,子树累乘+1就是方案数)
注意边界情况 因为每次是奇数的时候我们在已经设置了两个节点 (一个节点是2 另一个节点是一个子树的根)
如果剩下k=2了 那么就不再需要加了 如果k=3 就只需要再加一个节点
点击查看代码
#include <bits/stdc++.h>
using namespace std;
pair<int,int>a[100010];
int ans=0;
int cnt=1;
int main()
{
long long k=0;
cin>>k;
while(k){
if(k==2)break;
if(k==3){
a[++ans]={cnt,cnt+1};
cnt++;
break;
}
if(k&1){
a[++ans]={cnt,cnt+1};
a[++ans]={cnt,cnt+2};
cnt+=2;
k=k/2;
continue;
}
a[++ans]={cnt,cnt+1};
cnt++;
k--;
}
cout<<cnt<<endl;
for(int i=1;i<=ans;i++){
cout<<a[i].first<<' '<<a[i].second<<endl;
}
return 0;
}