【菜鸟进阶之路】P5461 赦免战俘 题解笔记(持更)

题目
1、这题和杨辉三角很像,可以找规律:每一个数字都是它上方数字加上右上方数字再模2。

(1)2的n次方可以用二进制数左移的方式;

C语言中1<<n是什么意思

(2)register声明的变量会被放到CPU的寄存器里,不用从内存取,用时更短;

register int的使用

(3)C++中的a^b为按位异或,异或根据计算位是否相同决定结果位,如果相同结果位为0,否则为1。

2、赦免的函数是对称的,f(i,j)=f(j,i),可考虑用位运算,发现 i|j=111(7),得出以下判断式:
f(i,j)=((i|j)!=((1<<n)-1)?0:1)。

3、本题基本思路是分治,代码可以通过递归来实现(好写但用时长),每次递归将左上方的正方形清零,并再次递归剩余的三个正方形,当正方形的边长为2时结束递归。

4、找规律,然后打表。

(1)C 库函数 double pow(double x, double y) 返回 x 的 y 次幂;

C 库函数 - pow()

5、核心思想(方法):求下一个方阵的情况,逐行逐行的将当前方阵情况插入下方(在下面复制两次),最后再补0。

(1)头文件 #include < string > 里有一个本题特别重要的函数—— insert() 函数

C++中的insert()函数

(2)copy下洛谷 @渊源 大佬有趣的AC算法(转侵删)

		a[0]="01";                                            //第一行情况 
		a[1]="11";                                            //第二行情况 
		for(long I=2;I<=n;I++){                               //现在是第几个方阵(即求输入I的输出结果)(**分治思想**) 
		for(long i=A[I-1];i<A[I];i++){                        //新增行的行号(是第几行)
		   	a[i].insert(a[i].length(),a[i-A[I-1]]);       //在新一行尾部插入
		    a[i].insert(a[i].length(),a[i-A[I-1]]);           //**插入两次** 
		}
		for(long i=0;i<A[I-1];i++)                            //在头几行最前面插入A[I-1]个0(应该不需要解释了吧) 
		for(long j=0;j<A[I-1];j++)                            //字符串**存储时不带空格,输出才带空格** 
		    a[i].insert(0,"0");
	    }

原博客:题解 P5461 【赦免战俘】

6、找规律:
首先n要先变成2^n。
不难发现,对于第一行的最后一个(即(1,n)),为1。
从第二行开始,对于每一个数可以用它上一个的数+右上的一个数,然后再%2。
因为求出来之后这个数字就不会改变,而且只涉及到上一行,所以可以直接用一维数组来模拟(上一个数就是自身,右上的数就是后一个)。

(1)用位运算可以加快速度(强调第二遍);

(2)ios::sync_with_stdio(false); 加快cin cout输入输出;

关于std::ios::sync_with_stdio(false)

(2020/5/27 22:28 明天继续做大自然的搬运工,看题解真的能收获良多~)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值