博客
关于我
Number Game( ZOJ - 3180,思维 + 逆推)
阅读量:251 次
发布时间:2019-03-01

本文共 2574 字,大约阅读时间需要 8 分钟。

分析问题并优化代码:

要解决这个问题,我们需要判断通过若干次操作是否可以将给定的三个数x、y、z转换为目标数组a、b、c(无序)。每次操作可以选择一个数赋值为剩下的两个数的和减一。由于正向操作可能导致数值急剧增加,因此我们采用逆推的方法,从目标数组反推可能的前驱状态。

逆推方法:

  • 排序数组:首先对目标数组进行排序,以便于比较和状态管理。
  • 生成前驱状态:对于每一个数,生成其可能的前驱值。例如,如果当前数为c,可能的前驱包括a、b和另一个由a和b生成的数。
  • 筛选有效状态:确保生成的前驱状态不会导致无限循环,例如,当所有数都为1或0时,需要特殊处理。
  • 循环反推:反复生成前驱状态,直到找到初始状态或判断无法达成目标。
  • 代码优化:

    • 去除不必要的语法错误:修正变量赋值和初始化部分,确保代码结构正确。
    • 简化状态生成:优化状态生成逻辑,确保每一步生成唯一的前驱状态,避免重复。
    • 添加循环终止条件:增加计数器和状态检查,防止无限循环,确保算法在合理步骤内终止。

    代码实现:

    #include 
    #include
    #include
    using namespace std;bool check(const vector
    & a, const vector
    & c) { if (a.size() != c.size()) return false; for (int i = 0; i < 3; ++i) { bool equal = true; for (int j = 0; j < 3; ++j) { if (a[j] != c[j]) { equal = false; break; } } if (equal) return true; } return false;}bool fun(vector
    a, vector
    b) { sort(a.begin(), a.end()); sort(b.begin(), b.end()); // 初始状态是否为目标 if (check(a, b)) return true; // 生成前驱状态 vector
    > prevStates; { vector
    state = {b[1], b[2]-1, b[1]}; sort(state.begin(), state.end()); prevStates.push_back(state); } { vector
    state = {b[0]+b[2]-1, b[0], b[2]}; sort(state.begin(), state.end()); prevStates.push_back(state); } { vector
    state = {b[0], b[1], b[0]+b[1]-1}; sort(state.begin(), state.end()); prevStates.push_back(state); } // 进行反推 int count = 0; while (true) { ++count; if (check(a, b)) return true; if (a[0] >= b[0] && a[1] >= b[1] && a[2] >= b[2]) { // 无法继续反推,无法达成目标 return false; } // 生成下一个状态 if (a[2] == a[1] - a[0] + 1) { a[2] = a[1] - a[0] + 1; } else { // 构造可能的下一个状态 vector
    newA = a; sort(newA.begin(), newA.end()); if (newA[0] == b[0] && newA[1] == b[1] && newA[2] == b[2]) { return true; } return false; } }}int main() { int T; scanf("%d", &T); while (T--) { vector
    a(3); vector
    b(3); for (int i = 0; i < 3; ++i) { scanf("%d", &a[i]); scanf("%d", &b[i]); } if (fun(a, b)) { printf("Yes\n"); } else { printf("No\n"); } } return 0;}

    代码说明:

    • check函数:用于比较两个数组是否相等,用于验证当前状态是否为目标状态。
    • fun函数:执行逆推操作,生成可能的前驱状态,判断是否能反推到初始状态。
    • main函数:读取输入,调用fun函数判断结果,并输出Yes或No。

    通过这种方法,我们可以有效地判断是否可以通过给定的操作将x、y、z转换为a、b、c。代码优化后更高效,能够处理各种情况,包括特殊情况的无限循环问题。

    转载地址:http://vyht.baihongyu.com/

    你可能感兴趣的文章
    NIFI大数据进阶_离线同步MySql数据到HDFS_02_实际操作_splitjson处理器_puthdfs处理器_querydatabasetable处理器---大数据之Nifi工作笔记0030
    查看>>
    NIFI大数据进阶_连接与关系_设置数据流负载均衡_设置背压_设置展现弯曲_介绍以及实际操作---大数据之Nifi工作笔记0027
    查看>>
    NIFI数据库同步_多表_特定表同时同步_实际操作_MySqlToMysql_可推广到其他数据库_Postgresql_Hbase_SqlServer等----大数据之Nifi工作笔记0053
    查看>>
    NIFI汉化_替换logo_二次开发_Idea编译NIFI最新源码_详细过程记录_全解析_Maven编译NIFI避坑指南001---大数据之Nifi工作笔记0068
    查看>>
    NIFI集群_内存溢出_CPU占用100%修复_GC overhead limit exceeded_NIFI: out of memory error ---大数据之Nifi工作笔记0017
    查看>>
    NIFI集群_队列Queue中数据无法清空_清除队列数据报错_无法删除queue_解决_集群中机器交替重启删除---大数据之Nifi工作笔记0061
    查看>>
    NIH发布包含10600张CT图像数据库 为AI算法测试铺路
    查看>>
    Nim教程【十二】
    查看>>
    Nim游戏
    查看>>
    NIO ByteBuffer实现原理
    查看>>
    Nio ByteBuffer组件读写指针切换原理与常用方法
    查看>>
    NIO Selector实现原理
    查看>>
    nio 中channel和buffer的基本使用
    查看>>
    NIO三大组件基础知识
    查看>>
    NIO与零拷贝和AIO
    查看>>
    NIO同步网络编程
    查看>>
    NIO基于UDP协议的网络编程
    查看>>
    NIO笔记---上
    查看>>
    NIO蔚来 面试——IP地址你了解多少?
    查看>>
    NISP一级,NISP二级报考说明,零基础入门到精通,收藏这篇就够了
    查看>>