HDU7321-KongMingQi孔明棋(找规律)

题意:给你规定初始状态有n*m个棋子,放到(n+2)*(m+2)的矩阵棋盘上,除了四条外边,其余各放一枚棋子。孔明棋在棋盘内移动一颗棋子的必要条件是:棋子的起点和终点之间有且仅有一个格子,并且格子上必须有一颗棋子,终点没有棋子,图示如下。问最后最少能剩多少棋子。

思路:先看懂下图的转换过程:

 

可以发现图4比图1少了个1x3的小矩阵,可以用上述操作在这三列上消去很多1x3矩阵。若操作到这三列只剩一个2x3的小矩阵,可以从上述图3转到下面操作,将两排同时消去:

可以看出这两种操作的条件都是要行数大于1并且由于第二种操作需要借助最左边一列辅助,所以列数要大于等于4。所以我们可以得出个小结论:若矩阵行数大于1、列数大于等于4,就可以消去三列,也就是if(n>1&&m>=4): n*m\rightarrow n*(m-3)重复这个操作就可以将矩阵列数变到4以内。由于此题行列等价n*m\rightarrow m*n,所以重复此操作可以将n和m都缩小到小于4的范围。n或者m等于1的情况可以直接计算。其余只剩2*2,2*3,3*3的情况,可以手动模拟得出结果。

#include<bits/stdc++.h>
using namespace std;

int main()
{
	int T;
	cin >> T;
	while (T--)
	{
		int n, m;
		cin >> n >> m;
		//1特判就行了 
		if (n == 1)
		{
			cout << (m + 1) / 2 << endl;
			continue;
		}
		if (m == 1)
		{
			cout << (n + 1) / 2 << endl;
			continue;
		}
		while (n >= 4)
		{
			n -= 3;
		}
		while (m >= 4)
		{
			m -= 3;
		}
		//减完若又出现1 
		if (n == 1)
		{
			cout << (m + 1) / 2 << endl;
			continue;
		}
		if (m == 1)
		{
			cout << (n + 1) / 2 << endl;
			continue;
		}
		//3种情况直接得出答案 
		if (n + m == 4)//2*2
		{
			cout << 1 << endl;
		}
		else if(n+m==5)//2*3或者3*2 
		{
			cout << 2 << endl;
		}
		else if (n + m == 6)//3*3
		{
			cout << 2 << endl;
		}
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值