hdu 6048 Puzzle(规律+逆序对)



Puzzle

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 92    Accepted Submission(s): 48


Problem Description
A Jigsaw puzzle contains N*M-1 pieces of jigsaws in a N rows*M columns rectangular board.Each jigsaw has a distinct number from 1 to N*M-1.Li is a naughty boy,he wants to arrange the board in his unique way.At the beginning,he picks all N*M-1 jigsaws out and put them on the table and then he will put them back to the board respecting the following steps:
1.Sorting all the remaining jigsaws on the table in ascending order.
2.Picking out the 1st ,the P+1 th ,the 2*P+1 th,......the n*P+1 th jigsaws and put them back to the blank area in the board one by one from the top row to the bottom row,from the left column to the right column.
3.if there are jigsaws remained on the table,back to step 1.
After he arranging the board,it’s obvious that there’s only one blank area located at the bottom-right corner.
Your task is to make the numbers on jigsaws sorted with every row and every column in ascending order(From left to right,top to bottom),and the blank area should be located at the bottom-right corner in the end.Each step you can move the blank area’s neighboring jigsaws(which share a common side with the blank area) towards the blank area.It’s really a difficult question,so you need to write a program to judge whether it is possible to complete the task.



 

Input
The first line contains an integer T(T<=100),which represents the number of test cases.
Following T lines,each line contains three integers N,M,P(2<=N,M<=1000;1<=P<=N*M-2).
 

Output
For each test case,print “YES” in a separate line if it is possible to complete the task ,otherwise please print “NO”.
 

Sample Input
  
  
3 3 2 3 3 2 4 999 999 1
 

Sample Output
  
  
YES NO YES
 

Source
 

Recommend
liuyiding
题意:

一个 n×m的滑块游戏,从左到右从上到下依次编号 1 n×m−1,最后一块是空的,现在把 n×m−1个滑块拿出来按编号升序排,每次把第 1,p+1,2p+1,…,np+1块拿出来从左到右从上到下放好,问放好后的局面是否可以恢复成编号为 i的滑块在第 i号位置的局面。

题解:

结论一:相邻的两个数字块交换位置改变序列逆序对数量的奇偶性。

结论二:白块左右移动不会改变逆序对的数量。

结论三:白块上下移动最终不会改变逆序对数量的奇偶性。因为白块每向上或向下移动一位相当于对应的数字块向下或向上移动 m−1次,而白块一定是从右下角最终回到右下角,移动偶数次,数字块也移动偶数次,不会改变逆序对数量的奇偶性。

结论四:任何规模的拼图最终一定会成为只有右下角 2×2的方格不确定的情况,枚举可能的 6种情况,发现逆序对数量奇偶性相同的情况可以互达。

结论五:由以上结论可知,任何局面一定可以转化为右下角 2×2方格不确定的情况而逆序对数量奇偶性不变,而最后有序情况的逆序对数量为 0,因此只需判断最开始情况逆序对的数量,若为偶数就可以复原,反之不能复原。

求逆序对时,可以累加每个数字后面比它小的数字的个数,即累加每个数字对逆序对的贡献。设当前轮剩余的数字数量为 tot,则这一轮可以取到的数字个数为 (tot−1)/p+1,其中除第一个数不贡献逆序对数之外,其余的 num=(tot−1)/p个数每个数贡献的逆序对数量构成首项为 p−1,公差为 p−1的等差数列,求和化简后的公式为 num∗(num+1)/2∗(p−1)

代码:
#include <cstdio>
#include <map>
#include <cstring>
#include <algorithm>
#include<iostream>
#include<cmath>
#define ll long long
using namespace std;
int n, m, p;
int main() {
   int t, temp, num, Count;
   scanf("%d", &t);
   while(t--) {
        Count = 0;
        scanf("%d%d%d", &n, &m, &p);
        num = n *m - 1;
        while(num > p) {
            temp = (num-1) / p + 1;
            Count += temp*(temp-1)/2*(p-1);
            num -= temp;
        }

        if(Count & 1)
            printf("NO\n");
        else
            printf("YES\n");
   }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值