Young Table

题意: 对一个每个数都唯一的动态矩阵每次进行两个数的位置交换操作(交换次数不超过总个数), 要求最终结果矩阵满足左到右为小到大,上到下为小大。输出变换个数和过程。


分析: 最终结果就是矩阵排序后的结果。 然后原矩阵按最终结果矩阵来移动。一个个放到正确位置的操作个数最多不会超过总数字个数。


所以:一个个放。


#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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值