比赛 20241022 评测结果 AAAAAAAAAAAAAAWWWWAA
题目名称 移球游戏 最终得分 80
用户昵称 darkMoon 运行时间 1.852 s
代码语言 C++ 内存使用 7.38 MiB
提交时间 2024-10-22 11:03:14
显示代码纯文本
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
using namespace std;
auto IN = freopen("2020ball.in", "r", stdin);
auto OUT = freopen("2020ball.out", "w", stdout);
auto mread = [](){int x;scanf("%d", &x);return x;};
const int N = 55, M = 405;
int n = mread(), m = mread();
deque<int> a[N];
queue<pair<int, int> > ans;
void make(int x, int y){
    ans.push(mp(x, y));
    a[y].push_back(a[x].back());
    a[x].pop_back();
    return;
}
void solve(int x, queue<int> q){
    // x 这个柱子,q 里面的索引位置要提到最上面,q 的索引降序排序

    // printf("*** ");
    // for(int i = 1; i <= m; i ++){
    //     printf("%lld ", a[x][i]);
    // }
    // printf("\n");
    int y = n;
    if(x == y){
        y = 1;
    }
    int len = q.size();
    for(int i = 1; i <= len; i ++){
        make(y, n + 1);
    }
    int sum = 0;
    for(int i = m; i >= 1; i --){
        if(q.size() == 0){
            break;
        }
        if(q.size() && q.front() == i){
            make(x, y);
            q.pop();
        }
        else{
            sum ++;
            make(x, n + 1);
        }
    }
    for(int i = 1; i <= sum; i ++){
        make(n + 1, x);
    }
    for(int i = 1; i <= len; i ++){
        make(y, x);
    }
    for(int i = 1; i <= len; i ++){
        make(n + 1, y);
    }
    return;
}
signed main(){
    for(int i = 1, x; i <= n; i ++){
        a[i].push_back(0);
        for(int j = 1; j <= m; j ++){
            cin >> x;
            a[i].push_back(x);
        }
    }
    // for(int i = 1; i <= n; i ++){
    //     queue<int> tmp;
    //     for(int j = m; j >= 1; j --){
    //         if(a[i][j] != i){
    //             tmp.push(j);
    //         }
    //     }
    //     solve(i, tmp);
    // }
    for(int i = 1; i <= n; i ++){
        queue<int> tmp;
        for(int k = i; k <= n; k ++){
            while(tmp.size()){
                tmp.pop();
            }
            for(int j = m; j >= 1; j --){
                if(k == i && a[k][j] != i){
                    tmp.push(j);
                }
                else if(k != i && a[k][j] == i){
                    tmp.push(j);
                }
            }
            solve(k, tmp);
        }
        int sum = 0;
        for(int j = 1; j <= m; j ++){
            if(a[i][j] != i){
                sum ++;
            }
        }
        for(int j = 1; j <= sum; j ++){
            make(i, n + 1);
        }
        for(int j = i + 1; j <= n; j ++){
            int tmp = 0;
            for(int k = 1; k <= m; k ++){
                if(a[j][k] == i){
                    tmp ++;
                    sum --;
                    assert(sum >= 0);
                }
            }
            for(int k = 1; k <= tmp; k ++){
                make(j, i);
            }
            for(int k = 1; k <= tmp; k ++){
                make(n + 1, j);
            }
        }
        assert(sum == 0);
    }
    printf("%d\n", ans.size());
    while(ans.size()){
        printf("%d %d\n", ans.front().fi, ans.front().se);
        ans.pop();
    }
    return 0;
}