MLE求调
查看原帖
MLE求调
755005
cxt1111楼主2025/7/19 17:20
#include <bits/stdc++.h>
using namespace std;
const int N=55;
const int M=405;
const int MN=830000;
int l[MN],r[MN],cnt[N],a[N][M],t,ans1,m,n,p[N];
int color_count[N][N]; // 记录每个栈中每种颜色的数量
// 优化:添加边界检查和颜色计数更新
void move(int x,int y){
    if(cnt[x] <= 0) return; // 防止从空栈弹出
    if(ans1 >= MN-1) return; // 防止记录数组越界
    
    int color = a[x][cnt[x]];
    color_count[x][color]--; // 更新源栈颜色计数
    color_count[y][color]++; // 更新目标栈颜色计数
    
    ++ans1;
    l[ans1]=x;
    r[ans1]=y;
    a[y][++cnt[y]]=a[x][cnt[x]--];
}

// 优化:直接返回预计算的颜色计数
inline int count(int x,int y){
    return color_count[x][y];
}

// 修复:处理空栈情况
inline int top(int x){
    if(cnt[x] <= 0) return 0; // 返回0表示空栈
    return a[x][cnt[x]];
}

// 优化:直接将栈x中所有颜色为target的圆盘移动到栈y
void move_all_color(int x, int y, int target) {
    stack<int> temp;
    while(cnt[x] > 0) {
        if(top(x) == target) {
            move(x, y);
        } else {
            temp.push(top(x));
            move(x, n+1); // 临时移到辅助栈
        }
    }
    // 从临时栈移回
    while(!temp.empty()) {
        move(n+1, x);
        temp.pop();
    }
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    cin>>n>>m;
    
    // 初始化颜色计数
    memset(color_count, 0, sizeof(color_count));
    
    for(int i=1;i<=n;i++){
        cnt[i]=m;
        for(int j=1;j<=m;j++){
            cin>>a[i][j];
            color_count[i][a[i][j]]++; // 统计每种颜色的数量
        }
    }
    cnt[n+1]=0; // 初始化辅助栈
    for(int i=1;i<=n+1;i++) p[i]=i; // 初始化映射数组
    
    for(int now=n;now>=3;now--){
        // 使用优化的移动函数
        move_all_color(p[1], p[now], now);
        
        // 处理第二个栈
        while(count(p[2], now) > 0) {
            if(cnt[p[1]] < m) {
                move(p[2], p[1]);
            } else {
                move(p[2], p[now+1]);
            }
        }
        
        swap(p[1], p[now]);
        swap(p[2], p[now+1]);
        
        for(int k=1;k<now;k++){
            move_all_color(p[k], p[now], now);
            swap(p[k], p[now]);
            swap(p[k], p[now+1]);
        }
        
        // 清理
        for(int i=1;i<now;i++) {
            while(top(p[i]) == now) {
                move(p[i], p[now+1]);
            }
        }
        for(int i=1;i<now;i++) {
            while(cnt[p[i]] < m && cnt[p[now]] > 0) {
                move(p[now], p[i]);
            }
        }
    }
    
    // 处理n=2的情况
    t=count(p[1],1);
    for(int i=1;i<=t;i++) move(p[2],p[3]);
    for(int i=1;i<=m;i++) {
        if(top(p[1])==1) move(p[1],p[2]);
        else move(p[1],p[3]);
    }
    for(int i=1;i<=t;i++) move(p[2],p[1]);
    for(int i=1;i<=m-t;i++) move(p[3],p[1]);
    while(cnt[p[3]]) move(p[3],p[2]);
    for(int i=1;i<=m-t;i++) move(p[1],p[3]);
    for(int i=1;i<=m;i++) {
        if(top(p[2])==1) move(p[2],p[1]);
        else move(p[2],p[3]);
    }
    
    cout<<ans1<<endl;
    for(int i=1;i<=ans1;i++){
        cout<<l[i]<<" "<<r[i]<<endl;
    }
    
    return 0;
}
2025/7/19 17:20
加载中...