Just an Old Puzzle

Just an Old Puzzle

You are given a 4 × 4 grid, which consists of 15 number cells and an empty cell.
All numbers are unique and ranged from 1 to 15.
In this board, the cells which are adjacent with the empty cell can move to the empty cell.
Your task is to make the input grid to the target grid shown in the figure below.
In the following example (sample input), you can get the target grid in two moves.
Just an Old Puzzle_第1张图片
Input:
The first line contains an integer T (1 <= T <= 10^5) denoting the number of test cases.
Each test case consists of four lines each containing four space-separated integers, denoting the input grid. 0 indicates the empty cell.
Output:
For each test case, you have to print the answer in one line.
If you can’t get the target grid within 120 moves, then print ‘No’, else print ‘Yes’.
Sample Input:
2
1 2 3 4
5 6 7 8
9 10 0 12
13 14 11 15
1 2 3 4
5 6 7 8
9 10 11 12
13 15 14 0
Sample Output:
Yes
No
杭电多校第四场G题
题目大意:给一个4*4的乱序数字华容道,求是否能将其恢复成顺序的。
题解:先对每个数字的现在位置和应在位置进行标记,从1开始遍历交换,交换一次ans就+1(初始值为0),注意,不能看有k个不在应在位置就直接ans=k,因为交换过程中,可能出现“交换一次,2个数字复位”的情况。由于空白位置的不确定性,开始还要加上空白位置的行列数。最后算出来的 ans%2,若ans==0,则可以实现(输出Yes),否则不能实现(输出No)。

#include 
using namespace std;
typedef long long ll;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int ans=0;
        int a[17];
        for(int i=1; i<=16; i++)
        {
            scanf("%d",&a[i]);
            if(a[i]==0)
            {
                a[i]=16;//把空白位置记为16号,方便写代码
                ans=ans+(i%4)+(i/4);//空白位置的行列数
                if(i%4!=0)
                    ans++;
            }
        }
        for(int i=1; i<=16; i++)
        {
            if(a[i]!=i)
            {
                ans++;
                for(int j=1; j<=16; j++)
                {
                    if(a[j]==i)//交换
                    {
                        int b=a[i];
                        a[i]=a[j];
                        a[j]=b;
                        break;
                    }
                }
            }
            int v=0;
            for(int ii=1; ii<=16; ii++)//每次交换完了都要判断
            {
                if(a[ii]!=ii)
                    v=1;
            }
            if(v==0)
            {
                if(ans%2==0)
                    printf("Yes\n");
                else
                    printf("No\n");
                break;
            }
        }
    }
    return 0;
}

你可能感兴趣的:(训练营)