1. 程式人生 > >Mail.Ru Cup 2018 Round 1 E. Chips Puzzle

Mail.Ru Cup 2018 Round 1 E. Chips Puzzle

題意:給你第一個n*m由01串構成的矩陣,你可以把x1行y1列的01串最後一個字元加到x2行y2列第一個字元上,要求你把第一個矩陣變成第二個輸入的矩陣,輸出操作過程。

2.思路:剛開始看題完全不會寫,翻了翻別人的ac程式碼,終於是找到了一份看懂的程式碼了,因此寫下了題解(別人的思路),這個構造題,直接把第一個矩陣變成第二個矩陣太難,但是我可以把第一個矩陣的所有0移動到1 1,把所有的1移動到2 1,第二個矩陣的01也移到這兩個地方,然後按正順序輸出第一個矩陣的移動過程,逆順序輸出第二個矩陣的移動過程即可(逆順序輸出就相當於1 1的所有0和2 1的所有1反過來移動形成第二個矩陣)。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=305,N=4e5;
int mv[N][2][2],vis[maxn][maxn],cnt=0;
string s;
void add(int x1,int y1,int x2,int y2)
{
	mv[++cnt][0][0]=x1;
	mv[cnt][0][1]=y1;
	mv[cnt][1][0]=x2;
	mv[cnt][1][1]=y2;
	++vis[x2][y2];
}
void Move(int x,int y,bool t)
{
	if(t)
	{
		if(x!=2)add(x,y,2,y);
		else add(x,y,2,y==1?2:1);
	}
	else
	{
		if(x!=1)add(x,y,1,y);
		else add(x,y,1,y==1?2:1);
	}
}
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		cin>>s;
		for(int k=s.size()-1;k>=0;k--)
		Move(i,j,s[k]=='1');
	}
	for(int i=1;i<=2;i++)
	for(int j=2;j<=m;j++)
	{
		for(int k=1;k<=vis[i][j];k++)
		add(i,j,i,1);
		vis[i][j]=0;
	}
	int tot=cnt;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		cin>>s;
		for(int k=0;k<s.size();k++)
		Move(i,j,s[k]=='1');
	}
	for(int i=1;i<=2;i++)
	for(int j=2;j<=m;j++)
	for(int k=1;k<=vis[i][j];k++)
	add(i,j,i,1);
	printf("%d\n",cnt);
	for(int i=1;i<=tot;i++)
	printf("%d %d %d %d\n",mv[i][0][0],mv[i][0][1],mv[i][1][0],mv[i][1][1]);
	for(int i=cnt;i>tot;i--)
	printf("%d %d %d %d\n",mv[i][1][0],mv[i][1][1],mv[i][0][0],mv[i][0][1]);
}