poj2286 唯美的IDA*(80行)

本文深入探讨了IDA*算法,一种结合了A*算法估价函数和深度优先搜索(DFS)特性的路径寻找算法。IDA*避免了A*所需的额外数据结构如哈希表和优先级队列,通过强大的剪枝策略提高了效率。

ida*果然比a*强太多了,少了hash判重和堆维护,是估价函数和DFS的完美结合啊!

嗯,主要是DFS函数中第二行的那个强剪枝太给力了!IDA*的灵魂啊!

基本的架构就是如此了,可以任意套。

//poj2286
#include <iostream>
#include <cmath>
using namespace std;
const int b[5][8] = { 7,8,9,12,13,16,17,18,
                      1,3,7,12,16,21,23,0,
                      2,4,9,13,18,22,24,0,
                      11,10,9,8,7,6,5,0,
                      20,19,18,17,16,15,14,0};
const int c[9] = {0,1,2,3,4,6,5,8,7};
int a[25],stk[1010],bound,x,final;
bool ans;
int h(int *a) {
    int tmp[3]={0,0,0};
    for (int i=0;i<8;i++)
        tmp[a[b[0][i]]-1]++;
    return 8-max(max(tmp[0],tmp[1]),tmp[2]);
}
void trans(int *a,int p) {
     if (p<=4) {
               int tmp = a[b[p][0]];
               for (int i=0;i<6;i++)
                   a[b[p][i]]=a[b[p][i+1]];
               a[b[p][6]]=tmp;
     } else {
               p-=4;
               int tmp = a[b[p][6]];
               for (int i=6;i>0;i--)
                   a[b[p][i]]=a[b[p][i-1]];
               a[b[p][0]]=tmp;
     }
}
int dfs(int *a,int dep,int pre_move) {
    int hv = h(a);
    if (hv + dep > bound) return hv+dep;
    if (hv==0) {
               ans = true;
               final = a[7];
               return dep;
    }
    int next_bound = 10000;
    for (int i=1;i<=8;i++) {
        if (abs(c[i]-pre_move)==4) continue;   //与上一步相反的移动
        int tmp[25];
        for (int j=1;j<=24;j++) tmp[j]=a[j];
        trans(tmp,c[i]);
        stk[dep]=i;
        int new_bound = dfs(tmp,dep+1,c[i]);
        if (ans) return new_bound;
        next_bound = min(next_bound,new_bound);
    }
    return next_bound;
}
void ida_star() {
     memset(stk,0,sizeof(stk));
     bound = h(a);
     ans = false;
     while (!ans && bound<=100)
           bound = dfs(a,0,-100);
     for (int i=0;i<bound;i++) printf("%c",stk[i]+64);
     printf("\n%d\n",final);
}
int main() {
    while (~scanf("%d",&x)) {
          if (x==0) break;
          a[1]=x;
          for (int i=2;i<=24;i++)
              scanf("%d",&a[i]);
                  
          if (h(a)==0) {
                    printf("No moves needed\n");
                    printf("%d\n",a[7]);
                    continue;
          }
          ida_star();
    }
    return 0;
}


### 关于 POJ 2286 的解决方案 POJ 平台上的题目编号通常对应特定算法或数据结构的应用场景。对于 POJ 2286,虽然未提供具体描述,但从其编号范围推测可能涉及动态规划、贪心策略或其他经典算法。 #### 动态规划方法 如果该问题是关于寻找友好数对的数量,则可以采用如下思路解决: 定义两个数组 `sum_divisors` 和 `friend_pairs` 来分别存储每个数的因子和以及已找到的友好数对数量。通过遍历小于给定上限的所有整数 \( n \),计算它们的因子之和并验证是否存在对应的友好数关系[^2]。 以下是实现这一逻辑的一个 Python 示例代码: ```python def calculate_friend_numbers(limit): sum_divisors = [0] * (limit + 1) # 计算所有数的因子和 for i in range(1, limit + 1): for j in range(i * 2, limit + 1, i): sum_divisors[j] += i friend_count = 0 seen_friends = set() # 验证每一对是否构成友好数字 for num in range(1, limit + 1): partner = sum_divisors[num] if ( partner < limit and partner != num and sum_divisors[partner] == num and (num, partner) not in seen_friends ): friend_count += 1 seen_friends.add((num, partner)) seen_friends.add((partner, num)) # 对称处理 return friend_count print(calculate_friend_numbers(10000)) # 输出小于一万的友好数量 ``` 上述代码实现了基于因子求和的方法来查找指定范围内所有的友好数对,并统计总数。 #### 数据结构优化 如果是类似于 **Balanced Lineup** 这样的区间最值查询问题,则需考虑高效的数据结构支持快速访问操作。例如使用线段树或者稀疏表(Sparse Table),可以在 O(log N) 或更低的时间复杂度下完成多次询问响应[^3]。 假设输入是一系列牛的高度序列,目标是最小化任意连续子列中的最大高度差。那么预处理阶段构建辅助索引之后,在每次请求到来时只需执常数级运算即可得出结果。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值