移球游戏求助
  • 板块灌水区
  • 楼主一E孤行
  • 当前回复5
  • 已保存回复5
  • 发布时间2021/10/13 21:37
  • 上次更新2023/11/4 03:53:15
查看原帖
移球游戏求助
229919
一E孤行楼主2021/10/13 21:37

RT,貌似发在灌水区里才有人看的样子(

只有40pts,在本地造的数据,会出现“temp.exe已停止运行”的状况,此时栈顶保存的元素 top[y]为负数,但是本人并没有找到哪里出了问题。

代码的思路是:利用分治,把球的颜色小于等于mid的看做1,其他的看做0,进行解决。

代码中有少量极丑的英文注释,为了防止我以后看不懂打的(

  • Code:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
int a[53][402],top[402],cnt,ans[820005][3];
void move(int x,int y) { //move x -> y
    top[y]++;
    a[y][top[y]]=a[x][top[x]];
    top[x]--; //move the ball

    cnt++;
    ans[cnt][0]=x,ans[cnt][1]=y; //get the ans
}
int n,m;
bool flag[402];
void divi(int l,int r) {
    if(l==r) return;
    memset(flag,0,sizeof(flag));
    int mid=(l+r)>>1;
    for(int I=1;I<=mid;I++) {
        for(int J=mid+1;J<=r;J++) {
            int i=I,j=J;
            if(flag[i] || flag[j]) continue;
            int sum=0;
            for(int k=1;k<=m;k++) {
                sum+=(a[i][k] <= mid);
                sum+=(a[j][k] <= mid);
            } // get the sum of the val of ther ball which is <= mid , recognize them to 1 , if sum >= m , make m balls which number is 1 to i , other make to j
            if(sum >= m) {
                sum=0;
                for(int k=1;k<=m;k++) sum+=(a[i][k] <= mid);
                for(int k=1;k<=sum;k++) move(j,n+1);
                while(top[i]) {
                    a[i][top[i]] <= mid ? move(i,j) : move(i,n+1);
                }
                for(int k=1;k<=sum;k++) move(j,i);
                for(int k=1;k<=m-sum;k++) move(n+1,i);
                for(int k=1;k<=m-sum;k++) move(j,n+1);
                for(int k=1;k<=m-sum;k++) move(i,j);
                while(top[n+1]) {
                    if(top[i]==m || a[n+1][top[n+1]] > mid) move(n+1,j);
                    else move(n+1,i);
                }
                flag[i]=1;
            } else {
                swap(i,j);
                sum=0;
                for(int k=1;k<=m;k++) sum+=(a[i][k] > mid);
                for(int k=1;k<=sum;k++) move(j,n+1);
                while(top[i]) {
                    a[i][top[i]] > mid ? move(i,j) : move(i,n+1);
                }
                for(int k=1;k<=sum;k++) move(j,i);
                for(int k=1;k<=m-sum;k++) move(n+1,i);
                for(int k=1;k<=m-sum;k++) move(j,n+1);
                for(int k=1;k<=m-sum;k++) move(i,j);
                while(top[n+1]) {
                    if(top[i]==m || a[n+1][top[n+1]] <= mid) move(n+1,j);
                    else move(n+1,i);
                }
                flag[i]=1;
            }
        }
    }
    divi(l,mid);
    divi(mid+1,r);
}
int main() {
#ifdef LOCAL
    freopen("in.in","r",stdin);
    freopen("out.out","w",stdout);
#endif
    //========================================
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) 
        for(int j=1;j<=m;j++) 
            scanf("%d",&a[i][j]),top[i]++;
    divi(1,n);
    printf("%d\n",cnt);
    for(int i=1;i<=cnt;i++) 
        printf("%d %d\n",ans[i][0],ans[i][1]);
    //========================================
    return 0;
}
2021/10/13 21:37
加载中...