hdu 6048puzzle (逆序对)

Puzzle

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


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

题意:
给你n*m的矩阵,元素分别是1,2,3.....n*m-1,按照1,,2p+1,3p+1,....的顺序循环放入矩阵,问你最后放好后你能否按照移动使矩阵里的元素按照升序排列

解析:
找规律,就是把矩阵的元素按从上到下,从左往右的顺序放到一个一维数组里,若该数组逆序对个数是偶数的话,则有解反之无解





最后计算逆序对数的时候,因为他是按1,p+1,2p+1,...的规律放的,所以可以通过计算每一组内每一次的放入的贡献值来求。一组内,第一次放入一定是当前剩余数组里面最小的元素,所以贡献值为0。第二次放入的是当前第p+1大的数,所以贡献值是p-1(他前面还有p-1个数还没放入),第三次放入的是当前第2p+1大的数,所以贡献值是2(p-1)(因为他前面有2*(p-1)个数没有放入,(加上了之前的p-1个))所以每一组就是以0为首项,p-1为公差,项数为(num-1)/p+1的等差数列



#include<stdio.h>


int main()
{
    int t,n,m,p;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&m,&p);
        int num=n*m-1;
        int k,ans;
        ans=0;
        while(num>p)
        {
            k=(num-1)/p+1;
            num-=k;
            ans+=(k*(k-1)*(p-1))/2;
        }
        if(ans%2)
            printf("NO\n");
        else
            printf("YES\n");
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值