题意: 对一个每个数都唯一的动态矩阵每次进行两个数的位置交换操作(交换次数不超过总个数), 要求最终结果矩阵满足左到右为小到大,上到下为小大。输出变换个数和过程。
分析: 最终结果就是矩阵排序后的结果。 然后原矩阵按最终结果矩阵来移动。一个个放到正确位置的操作个数最多不会超过总数字个数。
所以:一个个放。
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#define MAX 1005
#include <complex>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <string>
#define INF 1e8
#define MAX (int)1005
#define mkpr(i, j) make_pair(i, j)
using namespace std;
typedef pair<int, int> Pos;
int preMap[MAX][MAX], croMap[MAX][MAX];
int c[MAX], tVal[MAX * MAX], n;
Pos find(int val){
for(int i = 0; i < n; i++){
for(int j = 0; j < c[i]; j++){
if(preMap[i][j] == val){
return make_pair(i, j);
}
}
}
}
int main()
{
while(cin>>n){
for(int i = 0; i < n ; i++)cin>>c[i];
int a, m = 0;
for(int i = 0; i < n; i++){
for(int j = 0; j < c[i]; j++, m++){
cin>>a;
preMap[i][j] = a;
tVal[m] = a;
}
}sort(tVal, tVal+ m);
for(int i = 0, k = 0;i < n ;i++){
for(int j = 0; j < c[i]; j++, k++){
croMap[i][j] = tVal[k];
}
}
int sCount = 0;
vector<pair<Pos, Pos> > ans;
Pos res;
for(int i = 0; i < n; i++){
for(int j =0; j < c[i]; j++){
if(preMap[i][j]!= croMap[i][j]){
sCount ++;
res = find(croMap[i][j]);
swap(preMap[i][j], preMap[res.first][res.second]);
ans.push_back(mkpr(res, mkpr(i, j)));
}
}
}
cout<<sCount<<endl;
Pos pre, end;
for(int i = 0; i < sCount; i++){
pre = ans[i].first; end = ans[i].second;
cout<<pre.first + 1<<" "<<pre.second + 1<<" "<<end.first + 1<<" "<<end.second + 1<<endl;
}
}
return 0;
}