POJ2893 M * N Puzzle 逆序对

这篇博客主要解析了POJ2893 M * N Puzzle问题,探讨了在不同N值下逆序对数的奇偶性规律,并提供了通过测试的AC代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接

http://poj.org/problem?id=2893

分析

此处有一结论:将数码按原有顺序写成一列并除去 0 0 0 后,

N N N 为奇数,则初始状态和目标状态逆序对数奇偶性相同;

N N N 为偶数,则初始状态逆序对数加上 0 0 0 在两种状态下行数之差与目标状态逆序对数奇偶性相同。

AC代码

#include <cstdio>
#include <cstring>

inline int read() {
	int num = 0;
	char c = getchar();
	while (c < '0' || c > '9') c = getchar();
	while (c >= '0' && c <= '9')
		num = num * 10 + c - '0', c = getchar();
	return num;
}

const int maxn = 1e3 + 5;

int tot, bit[maxn * maxn];

inline int ask(int x) {
	int ret = 0;
	while (x) ret += bit[x], x -= x & -x;
	return ret;
}

inline void add(int x, int d) {
	while (x <= tot) bit[x] += d, x += x & -x;
}

int main() {
	int m, n, pos;
	while (scanf("%d%d", &m, &n) == 2 && m && n) {
		memset(bit, 0, sizeof(bit));
		tot = m * n - 1;
		long long cnt = 0;
		for (int i = 1; i <= m; ++i)
			for (int j = 1; j <= n; ++j) {
				int x = read();
				if (x) cnt += ask(tot) - ask(x), add(x, 1);
				else pos = i;
			}
		if (n & 1) {
			if (cnt % 2 == 0) printf("YES\n");
			else printf("NO\n");
		} else {
			if ((cnt + pos - 1) % 2 == 0) printf("YES\n");
			else printf("NO\n");
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值