poj2893 M × N Puzzle

来源:互联网 发布:目前常见软件架构 编辑:程序博客网 时间:2024/05/29 17:54

M × N Puzzle
Time Limit: 4000MS Memory Limit: 131072KTotal Submissions: 3332 Accepted: 940

Description

The Eight Puzzle, among other sliding-tile puzzles, is one of the famous problems in artificial intelligence. Along with chess, tic-tac-toe and backgammon, it has been used to study search algorithms.

The Eight Puzzle can be generalized into an M × N Puzzle where at least one of M and N is odd. The puzzle is constructed with MN − 1 sliding tiles with each a number from 1 to MN − 1 on it packed into a M by N frame with one tile missing. For example, with M = 4 and N = 3, a puzzle may look like:

16240375910811

Let's call missing tile 0. The only legal operation is to exchange 0 and the tile with which it shares an edge. The goal of the puzzle is to find a sequence of legal operations that makes it look like:

12345678910110

The following steps solve the puzzle given above.

START

16240375910811

DOWN

10246375910811
LEFT
12046375910811

UP

12346075910811

 

RIGHT

12340675910811

UP

12345670910811
UP
12345678910011

LEFT

12345678910110

GOAL

Given an M × N puzzle, you are to determine whether it can be solved.

Input

The input consists of multiple test cases. Each test case starts with a line containing M and N (2 ≤ MN ≤ 999). This line is followed by M lines containing N numbers each describing an M × N puzzle.

The input ends with a pair of zeroes which should not be processed.

Output

Output one line for each test case containing a single word YES if the puzzle can be solved and NO otherwise.

Sample Input

3 31 0 34 2 57 8 64 31 2 54 6 911 8 103 7 00 0

Sample Output

YESNO

Source

POJ Monthly--2006.07.30, newton88518



规律题,正好之前证过规律大概就是整个局面的逆序数+起始0的位置的坐标(x,y)中xy的和+rol+col+rol*col-1的奇偶

稍微证一下,

如果左右移动,那么起始的0的位置和终止0的位置四个坐标值相加一定是奇数,然后移动了逆序数肯定也奇偶变化,所以移动后奇偶值不变

上下移动,0的位置照样和是奇数,然后,取中间一段(0,a,b,c,d,e)变成(e,a,b,c,d,0),那么如果列为奇数,那么0往前移动关于0的逆序对奇偶不变,关于e的奇偶也不变,如果列为偶数,两个都变化总奇偶也不变。

所以,只要保证奇偶不变就能走到,奇偶变了就走不到了

#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;#define MAXN 1000005struct Tree{    int l,r,val;};Tree tree[MAXN*5];int n;void Build(int t,int l,int r){    tree[t].val=0;    tree[t].l=l;    tree[t].r=r;    if (l==r) return;    int mid=(l+r)/2;    Build(2*t+1,l,mid);    Build(2*t+2,mid+1,r);}int Count(int t,int l,int r){    if (tree[t].l==l && tree[t].r==r) return tree[t].val;    int ret=0;    int mid=(tree[t].l+tree[t].r)/2;    if (l<=mid) ret+=Count(2*t+1,l,min(r,mid));    if (r>mid) ret+=Count(2*t+2,max(l,mid+1),r);    return ret;}void Update(int t,int idx){    int l=tree[t].l;    int r=tree[t].r;    if (l==r)    {        tree[t].val=1;        return;    }    int mid=(l+r)/2;    if (idx<=mid) Update(2*t+1,idx);    else Update(2*t+2,idx);    tree[t].val=tree[2*t+1].val+tree[2*t+2].val;}int main(){    int i,j,r,c,x;    while(1)    {        scanf("%d%d",&r,&c);        if (r==0 && c==0) break;        n=r*c;        Build(0,0,n-1);        long long sum=r+c+n-1;        for (i=0;i<r;i++)        {            for (j=0;j<c;j++)            {                scanf("%d",&x);                if (x==0)                {                    sum+=(i+j);                }                sum+=Count(0,x,n-1);              //  printf("%d: %lld\n",x,Count(0,x,n-1));                Update(0,x);            }        }        if (sum%2==0) printf("YES\n");        else printf("NO\n");    }    return 0;}


0 0
原创粉丝点击