Codeforces Round #402 (Div. 1) D. Parquet Re-laying(脑洞)

来源:互联网 发布:一个网站几个域名 编辑:程序博客网 时间:2024/06/01 08:29

Peter decided to lay a parquet in the room of size n × m, the parquet consists of tiles of size 1 × 2. When the workers laid the parquet, it became clear that the tiles pattern looks not like Peter likes, and workers will have to re-lay it.

The workers decided that removing entire parquet and then laying it again is very difficult task, so they decided to make such an operation every hour: remove two tiles, which form a 2 × 2 square, rotate them 90 degrees and put them back on the same place.

They have no idea how to obtain the desired configuration using these operations, and whether it is possible at all.

Help Peter to make a plan for the workers or tell that it is impossible. The plan should contain at most 100 000 commands.

Input

The first line contains integer n and m, size of the room (1 ≤ n, m ≤ 50). At least one of them is even number.

The following n lines contain m characters each, the description of the current configuration of the parquet tiles. Each character represents the position of the half-tile. Characters 'L', 'R', 'U' and 'D' correspond to the left, right, upper and lower halves, respectively.

The following n lines contain m characters each, describing the desired configuration in the same format.

Output

In the first line output integer k, the number of operations. In the next k lines output description of operations. The operation is specified by coordinates (row and column) of the left upper half-tile on which the operation is performed.

If there is no solution, output -1 in the first line.

Examples
input
2 3ULRDLRLRULRD
output
21 21 1
input
4 3ULRDLRLRULRDULRDUUUDDDLR
output
33 13 22 2
Note

分析:(我来翻译官方题解系列)

    假设整个矩阵的长度(水平)为偶数(如果不是那么交换一下长宽,长宽中至少有一个是偶数),然后我们设想把开始局面和最终局面同时旋转然后达到一个中间局面,因为所有操作都可逆,所以我们只需要要把对后者的所有操作倒过来拼到前边的操作上就行了。

  那么如何达到一个所有瓷砖都是水平放置这样一个中间局面呢?我们从上到下,从左到右开始,把所有的瓷砖都放置成正确位置,如果一个瓷砖是垂直放置的,那么我们我们就尝试转动它,如果因为相邻瓷砖的原因无法转动,那么我们就递归地处理它的邻居,这样我们就得到了如图所示的一个“梯子“,最多n层,而且梯子的最底层一定可以直接旋转,然后就没有然后了。

#include <bits/stdc++.h>#define MOD 10000007#define N 55using namespace std;typedef pair<int,int> pii;int n,m,flip,sta[N][N];char s[N];map <char,int> f;vector<pii> ans,ans1,ans2;void deal(int x,int y){    if(sta[x][y] == 1)    {        if(sta[x][y+1] != 1) deal(x,y+1);        sta[x][y] = sta[x+1][y] = 3;        sta[x][y+1] = sta[x+1][y+1] = 4;        ans.push_back(make_pair(x,y));    }    else    {        if(sta[x+1][y] != 3) deal(x+1,y);        sta[x][y] = sta[x][y+1] = 1;        sta[x+1][y] = sta[x+1][y+1] = 2;        ans.push_back(make_pair(x,y));    }}void deal(){    flip = !(n & 1);    for(int i = 1;i <= n;i++)     for(int j = 1;j <= m;j++)     {         if(!flip && sta[i][j] == 1) deal(i,j);         if(flip && sta[i][j] == 3) deal(i,j);     }}int main(){    f['U'] = 1;f['D'] = 2;f['L'] = 3;f['R'] = 4;    scanf("%d%d",&n,&m);    for(int i = 1;i <= n;i++)    {        scanf("%s",s+1);        for(int j = 1;j <= m;j++)         sta[i][j] = f[s[j]];    }    deal();    ans1 = ans;    ans.clear();    for(int i = 1;i <= n;i++)    {        scanf("%s",s+1);        for(int j = 1;j <= m;j++)         sta[i][j] = f[s[j]];    }    deal();    ans2 = ans;    cout<<ans1.size() + ans2.size()<<endl;    for(int i = 0;i < ans1.size();i++)    {        int u = ans1[i].first,v = ans1[i].second;        cout<<u<<" "<<v<<endl;    }    for(int i = ans2.size()-1;i >= 0;i--)    {        int u = ans2[i].first,v = ans2[i].second;        cout<<u<<" "<<v<<endl;    }}














0 0
原创粉丝点击