洛谷 P5461 赦免战俘 题解 C/C++

思路如下:

方法一:递归,初始化数组为0,;边长为1时结束,每次将符合条件的元素(即左上角)标记为1,递归右上角,右下角,左下角。
方法二:找规律:每一个数字都是它上方数字加上右上方数字再模2,用异或^也行;初始化数组 arr[0][l+1] = 1,其余为0

  • 法一 递归
//#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <cctype>
#include <sstream>
#define inf 0x3f3f3f3f
#define eps 1e-6
using namespace std;
#define clr(x) memset(x,0,sizeof((x)))
const int maxn = 1e5+1;//2e6+1
#define MAX(a,b,c) ((a)>(b)?((a)>(c)?(a):(c)):((b)>(c)?(b):(c)))
#define _max(a,b) ((a) > (b) ? (a) : (b))
#define _min(a,b) ((a) < (b) ? (a) : (b))
#define _for(a,b,c) for(int a = b;a<c;a++)
int arr[2000][2000];
void rec(int x,int y,int l) {
    
    
	if(l==1)return ;//边长为1时结束
	for(int i = x;i<l/2+x;i++) {
    
    
		for(int j = y;j<l/2+y;j++) {
    
    
			arr[i][j] = 1;//将符合条件的(左上角)元素标为1
		}
	}
	rec(x,y+l/2,l/2);//右上角
	rec(x+l/2,y+l/2,l/2);//右下角
	rec(x+l/2,y,l/2);//左下角

}
int main()
{
    
    
#ifdef LOCAL 
	freopen("data.in","r",stdin);
	freopen("data.out","w",stdout);
#endif
	int n,l;
	cin>>n;
	l = 1<<n;
	rec(0,0,l);//存入起点坐标、长度和宽度,因为是正方形长宽相等,存入一个即可
	for(int i = 0;i<l;i++) {
    
    
		for(int j = 0;j<l;j++) {
    
    
			printf("%d%c",arr[i][j]?0:1,j<l-1?' ':'\n');
		}
	}
    return 0;
}
  • 法二
//#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <cctype>
#include <sstream>
#define inf 0x3f3f3f3f
#define eps 1e-6
using namespace std;
#define clr(x) memset(x,0,sizeof((x)))
const int maxn = 1e5+1;//2e6+1
#define MAX(a,b,c) ((a)>(b)?((a)>(c)?(a):(c)):((b)>(c)?(b):(c)))
#define _max(a,b) ((a) > (b) ? (a) : (b))
#define _min(a,b) ((a) < (b) ? (a) : (b))
#define _for(a,b,c) for(int a = b;a<c;a++)

int arr[2000][2000];
int main()
{
    
    
#ifdef LOCAL 
	freopen("data.in","r",stdin);
	freopen("data.out","w",stdout);
#endif
	int n,l;
	cin>>n;
	l = 1<<n;
	arr[0][l+1] = 1;
	//每一个数字都是它上方数字加上右上方数字再模2。 用异或^也行
	for(int i = 1;i<=l;++i) {
    
    
		for(int j = 1;j<=l;++j) {
    
    
			arr[i][j] = (arr[i-1][j]+arr[i-1][j+1])%2;//arri][j] = arr[i-1][j] ^ arr[i-1][j+1];
			if(j==l)cout<<arr[i][j];//避免打出多余空格
			else cout<<arr[i][j]<<" ";
		}
		if(i<l)cout<<endl;//避免打出多余换行
	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Jason__Jie/article/details/113060265