UVa OJ 11212 - Editing a Book

来源:互联网 发布:颜值测试软件 编辑:程序博客网 时间:2024/06/07 10:25

UVa OJ 11212 - Editing a Book

(IDA*)

Problem

  你有一篇由n(2≤n≤9)个自然段组成的文章,希望将它们排列成1, 2,…, n。可以用 Ctrl+X(剪切)和Ctrl+V(粘贴)快捷键来完成任务。每次可以剪切一段连续的自然段,粘贴时按照顺序粘贴。注意,剪贴板只有一个,所以不能连续剪切两次,只能剪切和粘贴交替。

  例如,为了将{2,4,1,5,3,6}变为升序,可以剪切1将其放到2前,然后剪切3将其放到4 前。再如,对于排列{3,4,5,1,2},只需一次剪切和一次粘贴即可——将{3,4,5}放在{1,2}后, 或者将{1,2}放在{3,4,5}前。

Input

The input consists of at most 20 test cases. Each case begins with a line containing a single integer n (1 < n < 10), thenumber of paragraphs. The next line contains a permutation of 1, 2, 3, … , n. The last case is followed by a single zero, which should not be processed.

  输入的数据最多有二十种情况。每一种情况以一个整数n开头(1

Output

For each test case, print the case number and the minimal number of cut/paste operations.

输出每一种情况所需要移动的最少步骤。

Sample Input

62 4 1 5 3 653 4 5 1 20

Sample Output

Case 1: 2Case 2: 1

Solution

入门级的迭代加深搜索,题目不复杂,代码也不是很长。主要还是注意当前深度和乐观估计函数到底是什么。

不过虽然是这样说,自己debug的时候也是出了点状况的,比如在进行数据前后的交换时,一开始没注意n的范围,直接把交换的范围取到了9,导致出现莫名其妙的数据错误。orz

嘛,自己毕竟也是刚起步吧,一点点努力吧。下面就把代码贴出来,效率不高,见笑了。

#include <cstdio>#include <cstring>using namespace std;int n,maxd;int para[10];int geth(int a[]){    int num = 0;    for (int i = 1; i < n;++i)    if (a[i] + 1 != a[i + 1]) num++;    return num;}void change_para(int i,int j,int k, int a[]){    int temp1[10], temp2[10];    memcpy(temp1, a + i, sizeof(int)*j);    memcpy(temp2, a + i + j, sizeof(int)*k);    memcpy(a + i, temp2, sizeof(int)*k);    memcpy(a + i + k, temp1, sizeof(int)*j);}bool isok(int a[]){    for (int i = 1; i <= n;++i)        if (i != a[i]) return false;    return true;}bool dfs(int d,int paras[]){    if (d == maxd )        if (isok(paras)) return true;    int h = geth(paras);    if (3 * d + h <= 3 * maxd)        for (int i = 1; i < n; ++i)        for (int j = 1; j <= n - i; ++j)        for (int k = 1; k <= n+1 - i - j; ++k){            int new_para[10];            memcpy(new_para, paras, sizeof(int)*10);            change_para(i, j, k, new_para);            if (dfs(d+1, new_para)) return true;        }    return false;}int main(){    int cas = 0;    while (scanf("%d", &n) == 1 && n){        for (int i = 1; i <= n; ++i)            scanf("%d", &para[i]);        for (maxd = 0; maxd < n; ++maxd)            if (dfs(0,para)) break;        printf("Case %d: %d\n", ++cas,maxd);    }    return 0;}
0 0
原创粉丝点击