poj1033 磁盘碎片

模拟磁盘碎片整理,写的晕了~

方法:能移就移,不然处理其所在链或环

#include <iostream>
using namespace std;
int v[10010],id[10010],m,n,k,tot,x,r;
bool loop,f;
int main() {
    while (~scanf("%d%d",&m,&n)) {
          tot = 0;
          memset(v,0,sizeof(v));
          for (int i=1;i<=n;i++) {
              scanf("%d",&k);
              for (int j=1;j<=k;j++) {
                  scanf("%d",&x);
                  v[x] = ++tot;
                  id[tot] = x;
              }
          }
          f = true;
          for (int i=1;i<=m;i++) {
              if (v[i]>0 && v[v[i]]==0) {
                          printf("%d %d\n",i,v[i]);
                          f = false;
                          v[v[i]] = -1;
                          v[i] = 0;
              }
              if (v[i]>0 && v[v[i]]>=0) {
                          k = i;
                          loop = true;
                          while (v[k]!=i) {
                                if (v[k]==0) {
                                             loop = false;
                                             break;
                                }
                                k = v[k];
                          }
                          if (!loop) {
                                     k = id[k];
                                     while (1) {
                                           printf("%d %d\n",k,v[k]);
                                           f = false;
                                           v[v[k]] = -1;
                                           k = id[k];
                                           if (id[k]==0) {
                                                         printf("%d %d\n",k,v[k]);
                                                         f = false;
                                                         v[v[k]] = -1;
                                                         v[k] = 0;
                                                         break;
                                           }
                                     }
                          }
                          else {
                               if (v[k]==k) continue;
                               f = false;
                               for (r=m;r>=0;r--)
                                   if (v[r]==0) break;
                               printf("%d %d\n",k,r);
                               v[r] = v[k];
                               v[k] = 0;
                               id[v[r]] = r;
                               k = id[k];
                               while (1) {
                                           printf("%d %d\n",k,v[k]);
                                           v[v[k]] = -1;
                                           k = id[k];
                                           if (id[k]==0) {
                                                         printf("%d %d\n",k,v[k]);
                                                         v[v[k]] = -1;
                                                         v[k] = 0;
                                                         break;
                                           }
                               }
                          }
              }
          }
          if (f) printf("No optimization needed\n");
    }
    return 0;
}
                               


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值