热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

竞争性编程-代码在线编译器提供不同的答案

如何解决《竞争性编程-代码在线编译器提供不同的答案》经验,为你挑选了1个好方法。

我试图在codeforces上解决问题811C.我开始编写sublime-text编码,并设法在一段时间后提出解决方案.当我运行该程序时,它给了我正确的答案但是当我提交代码时,出于某种原因我得到了代码强制的不同答案.我检查了数组是否超出范围,但这似乎不是原因.这是代码:

/* Code Readability Credit : Max Vollmer */
#include 
#include 
#include 
#include 
#include 

// terms[] stores the value of all the terms. leftMosts[i] and rightMosts[i] store the leftmost and rightmost occurrences of the ith element in terms[]. 
//solvedValues[] stands for dynamic programming and stores the pre calculated terms of the function solve()
int numberOfTerms;
int terms[5005];
int leftMosts[5005];
int rightMosts[5005];
int solvedValues[5005];

int comf(int left,int right)// comf = comfort (see problem statement if you do not understand this)
{ 
    std::set track;
    int ret = 0;
    for(int i = left; i <= right; i++)
    {
        if (!track.count(terms[i]))
        {
            ret = (ret^terms[i]);
            track.insert(terms[i]);
        }
    }
    return ret;
}

// below, solve stands for 'solve', it is terms recursive memoized function
// returns max sequence from i to (numberOfTerms-1). to find max, call solve(0, -1) so i=0,lefmost=-1. leftmost keeps track of the position of last index of last chosen set.
int solve(int i, int leftmost)
{
    if (i >= numberOfTerms)
    {
        return 0;
    }

    if (solvedValues[i] != -1)
    {
        return solvedValues[i];
    }

    if (leftMosts[i] <= leftmost)
    {
        return solve(i+1, leftmost);// we cant go choose leftMosts[i] to rightMosts[i] so we move on
    }

    // decide if it is better to choose current leftMosts[i] to rightMosts[i] or better to simply move on and skip this.
    return solvedValues[i] = std::max(comf(leftMosts[i], rightMosts[i]) + solve(rightMosts[i]+1, rightMosts[i]), solve(i+1, leftmost));
}

void init()
{
    scanf("%d", &numberOfTerms);
    for(int i = 0; i  i; rightIndex--)
        {
            if (terms[rightIndex] == terms[i])
            {
                rightMosts[i] = rightIndex;
                break;
            }
        }

        if (leftMosts[i] == -1)
        {
            leftMosts[i] = i;// if there is no leftmost occ, then leftmost is current
        }

        if (rightMosts[i] == -1)
        {
            rightMosts[i] = i;// same as above for rightmost
        }
    }

    printf("%d\n", solve(0, -1));

    return 0;
}

这是测试用例:

100 931 4584 2116 3004 3813 62 2819 2998 2080 4906 3198 2443 2952 3793 1958 3864 3985 3169 3134 4011 4525 995 4163 308 4362 1148 4906 3092 1647 244 1370 1424 2753 84 2997 1197 2606 425 3501 2606 683 4747 3884 4787 2166 3017 3080 4303 3352 1667 2636 3994 757 2388 870 1788 988 1303 0 1230 1455 4213 2113 2908 871 1997 3878 4604 1575 3385 236 847 2524 3937 1803 2678 4619 1125 3108 1456 3017 1532 3845 3293 2355 2230 4282 2586 2892 4506 3132 4570 1872 2339 2166 3467 3080 2693 1925 2308

正确的输出应该是:

227685

Codeforces的错误输出:

245849

再次,在我的机器上,代码工作正常并输出227685但是当它在线运行时,代码输出245849由于某种原因.代码可以在这里在线测试. 这是在本地计算机上运行的代码的图像.

我很想知道造成这种情况的原因.

更新: 此错误是由于最终计算值设置为时未考虑leftmost函数中的变量引起的.这是对问题的错误/不正确的方法,并导致诸如影响代码输出的顺序之类的问题.solve(int i,int leftmost)solvedValues[i]std::max()



1> Max Vollmer..:

结果不同的原因

您使用的参数std::max在线和本地计算机上以不同的顺序执行.当comf(leftMosts[i], rightMosts[i]) + solve(rightMosts[i]+1, rightMosts[i])被执行之前solve(i+1, leftmost),你得到想要的结果.如果交换订单,则会得到错误的结果.

有效的重构代码

这是我重构的代码,以提高可读性.我所做的一件事就是打破长期的回报slv.如果切换线的顺序int a =...int b =...你会得到错误的结果:

#include 
#include 
#include 
#include 
#include 

// terms[] stores the value of all the terms. leftMosts[i] and rightMosts[i] store the leftmost and rightmost occurrences of the ith element in terms[]. 
//solvedValues[] stands for dynamic programming and stores the pre calculated terms of the function solve()
int numberOfTerms;
int terms[5005];
int leftMosts[5005];
int rightMosts[5005];
int solvedValues[5005];

int comf(int left,int right)
{ 
    std::set track;
    int ret = 0;
    for(int i = left; i <= right; i++)
    {
        if (!track.count(terms[i]))
        {
            ret = (ret^terms[i]);
            track.insert(terms[i]);
        }
    }
    return ret;
}

// below, solve stands for 'solve', it is terms recursive memoized function
// returns max sequence from i to (numberOfTerms-1). to find max, call solve(0, -1) so i=0,lefmost=-1. leftmost keeps track of the position of last index of last chosen set.
int solve(int i, int leftmost)
{
    if (i >= numberOfTerms)
    {
        return 0;
    }

    if (solvedValues[i] != -1)
    {
        return solvedValues[i];
    }

    if (leftMosts[i] <= leftmost)
    {
        return solve(i+1, leftmost);// we cant go choose leftMosts[i] to rightMosts[i] so we move on
    }

    // decide if it is better to choose current leftMosts[i] to rightMosts[i] or better to simply move on and skip this.
    int a = comf(leftMosts[i], rightMosts[i]) + solve(rightMosts[i]+1, rightMosts[i]);
    int b = solve(i+1, leftmost);
    return solvedValues[i] = std::max(a, b);
}

void init()
{
    scanf("%d", &numberOfTerms);
    for(int i = 0; i  i; rightIndex--)
        {
            if (terms[rightIndex] == terms[i])
            {
                rightMosts[i] = rightIndex;
                break;
            }
        }

        if (leftMosts[i] == -1)
        {
            leftMosts[i] = i;// if there is no leftmost occ, then leftmost is current
        }

        if (rightMosts[i] == -1)
        {
            rightMosts[i] = i;// same as above for rightmost
        }
    }

    printf("%d numberOfTerms", solve(0, -1));

    return 0;
}

我们从中学到了什么?

可读,干净的代码不仅对你的程序员(和你自己)很好,它还可以降低bug的风险.


推荐阅读
  • 我在尝试将组合框转换为具有自动完成功能时遇到了一个问题,即页面上的列表框也被转换成了自动完成下拉框,而不是保持原有的多选列表框形式。 ... [详细]
  • 题目描述:Balala Power! 时间限制:4000/2000 MS (Java/Other) 内存限制:131072/131072 K (Java/Other)。题目背景及问题描述详见正文。 ... [详细]
  • HDU 2537 键盘输入处理
    题目描述了一个名叫Pirates的男孩想要开发一款键盘输入软件,遇到了大小写字母判断的问题。本文提供了该问题的解决方案及实现方法。 ... [详细]
  • UVa 11683: 激光雕刻技术解析
    自1958年发明以来,激光技术已在众多领域得到广泛应用,包括电子设备、医疗手术工具、武器等。本文将探讨如何使用激光技术进行材料雕刻,并通过编程解决一个具体的激光雕刻问题。 ... [详细]
  • 在学习了Splay树的基本查找功能后,可能会觉得它与普通的二叉查找树没有太大的区别,仅仅是通过splay操作减少了时间开销。然而,Splay树之所以被誉为“序列之王”,主要在于其强大的区间操作能力。 ... [详细]
  • 如何使用Maven将依赖插件一并打包进JAR文件
    本文详细介绍了在使用Maven构建项目时,如何将所需的依赖插件一同打包进最终的JAR文件中,以避免手动部署依赖库的麻烦。 ... [详细]
  • 本文探讨了如何使用Scrapy框架构建高效的数据采集系统,以及如何通过异步处理技术提升数据存储的效率。同时,文章还介绍了针对不同网站采用的不同采集策略。 ... [详细]
  • 题目概述:Sereja 拥有一个由 n 个整数组成的数组 a1, a2, ..., an。他计划执行 m 项操作,这些操作包括更新数组中的特定元素、增加数组中所有元素的值,以及查询数组中的特定元素。 ... [详细]
  • 本文介绍了一种在 Android 开发中动态修改 strings.xml 文件中字符串值的有效方法。通过使用占位符,开发者可以在运行时根据需要填充具体的值,从而提高应用的灵活性和可维护性。 ... [详细]
  • 个人博客:打开链接依赖倒置原则定义依赖倒置原则(DependenceInversionPrinciple,DIP)定义如下:Highlevelmo ... [详细]
  • 本文探讨了如何选择一个合适的序列化版本ID(serialVersionUID),包括使用生成器还是简单的整数,以及在不同情况下应如何处理序列化版本ID。 ... [详细]
  • Hadoop MapReduce 实战案例:手机流量使用统计分析
    本文通过一个具体的Hadoop MapReduce案例,详细介绍了如何利用MapReduce框架来统计和分析手机用户的流量使用情况,包括上行和下行流量的计算以及总流量的汇总。 ... [详细]
  • Java连接MySQL数据库的方法及测试示例
    本文详细介绍了如何安装MySQL数据库,并通过Java编程语言实现与MySQL数据库的连接,包括环境搭建、数据库创建以及简单的查询操作。 ... [详细]
  • 本文旨在探讨Swift中的Closure与Objective-C中的Block之间的区别与联系,通过定义、使用方式以及外部变量捕获等方面的比较,帮助开发者更好地理解这两种机制的特点及应用场景。 ... [详细]
  • Gradle 是 Android Studio 中默认的构建工具,了解其基本配置对于开发效率的提升至关重要。本文将详细介绍如何在 Gradle 中定义和使用共享变量,以确保项目的一致性和可维护性。 ... [详细]
author-avatar
huanhuan199538
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有