[2017纪中11-1]序列 搜索+IDA*

来源:互联网 发布:数据脱敏方式 编辑:程序博客网 时间:2024/06/05 18:13

题面
每次将 n 翻转到 x1 再翻转到 xn,可以得到一个不超过2n-2 步的做法。由于步数不多,我们可以使用迭代加深搜索。
我们发现每次翻转只会改变一对相邻数对,因此对于一个状态求出相差>1 的相邻数对的数量,剩余步数一定大于这个值。加上这个剪枝就能通过本题。
代码:

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>using namespace std;int n,m,a[30];bool pd;inline void reverse(int k){    for(int i=1;i<=(k>>1);i++)        swap(a[i],a[k-i+1]);}inline bool check(){    for(int i=1;i<=n;i++)        if(a[i]!=i) return 0;    return 1;   }inline void dfs(int d){    int k=0;    for(int i=1;i<n;i++)        k+=(abs(a[i]-a[i+1])>1);    if(d+k>m) return;    if(check()){pd=1;return;}    for(int i=2;i<=n;i++)    {        reverse(i);        dfs(d+1);        reverse(i);        if(pd) return ;    }}int main(){    int ca;    scanf("%d",&ca);    while(ca--)    {        scanf("%d",&n);        for(int i=1;i<=n;i++)            scanf("%d",&a[i]);        for(m=0;;m++)        {            pd=0;            dfs(0);            if(pd) break;        }        printf("%d\n",m);    }    return 0;}
原创粉丝点击