10152 - ShellSort

题意:
本题与 "希尔排序" 无关, 应该是 "龟壳排序". "龟壳排序": 每次取一个龟壳(字符串), 把其移到最顶端, 其他的依次下移. 输入两组字符串, 第一组为初始串, 第二组为目标串. 求在使用 "龟壳排序" 的情况下, 将初始串变为目标串, 要求进行操作的次数最少. 

思路:
要使初始串移动后达到目标串, 很好做, 但要求最少的移动次数, 就不会了...
以下思路来自: http://www.kaixinwenda.com/article-hhaile-8108911.html
以初始序列为准,设初始序列下标为i, 目的序列下标为j, 从n-1开始,如果两下标对应的字符串相等,下标同时减一,否则仅初始序列下标减一。那么目的序列中还未被成功匹配的字符串就是需要移动的字符串。要使移动次数最少,显然应该按未被处理的目的序列中字符串逆序移动(输出).

要点:
stl distance 会返回负数吗? 不会, 如果 distance 的第二个参数所指位置在第一个参数之前, 则会绕回来. (在 list 里是这样的, 但是对于其他 container 不是很确定是否会是这样的行为).

题目:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=103&page=show_problem&problem=1093

代码:

# include <iostream>
# include <string>
# include <cstdio>
# include <cstring>
# include <vector>
# include <algorithm>
# include <cctype>
# include <iterator>
# include <assert.h>
# include <list>
using namespace std;

typedef list<string>::const_iterator LIT;

// 获取需要开始往上移动的字符串的 iterator
LIT getTurtlesToClimb(const list<string>& original, 
                      const list<string>& required) {
  LIT oi = original.begin();
  LIT ri = required.begin();

  while (oi != original.end() && ri != required.end()) {
    if (*oi == *ri) {
      ++oi;
      ++ri;
    } else {
      ++oi;
    }
  }

  return ri;
}

int main(int argc, char const *argv[])
{
  #ifndef ONLINE_JUDGE
    freopen("10152_i.txt", "r", stdin);  
    freopen("uva_o.txt", "w", stdout); 
  #endif
  
  int numCase;
  cin >> numCase;

  while (numCase--) {
    int numTurtles;
    cin >> numTurtles;
    cin.ignore();     // cin 之后要接 getline,一定要有 ignore

    list<string> original;
    list<string> required;
    string line;
    // input
    for (int i=0; i<numTurtles; i++) {
      getline(cin, line);
      original.push_front(line);
    }
    for (int i=0; i<numTurtles; i++) {
      getline(cin, line);
      required.push_front(line);
    }

    // 注意这里输出的是 require 中剩下的字符串,而不是 original 中的
    LIT ri = getTurtlesToClimb(original, required);
    copy(ri, static_cast<LIT>(required.end()), 
         ostream_iterator<string>(cout, "\n"));

    // 最后一个 case 也需要输出回车, 所以不需要以下行
    //if (numCase > 0) cout << endl;
    cout << endl;
  }
  
  return 0;
}

环境: C++ 4.5.3 - GNU C++ Compiler with options: -lm -lcrypt -O2 -pipe -DONLINE_JUDGE

转载于:https://my.oschina.net/zenglingfan/blog/148512

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值