Mail.Ru Cup 2018 Round 1 E. Chips Puzzle
阿新 • • 發佈:2018-11-22
題意:給你第一個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]); }