您当前的位置:首页 > 电脑百科 > 程序开发 > 算法

非典型算法题,用程序和电脑玩一个游戏

时间:2020-10-19 12:04:11  来源:  作者:

今天选择的算法题是来自contest 1407比赛的C题,这题全场通过6700余人。通过的人数虽然多,但是这题真的不简单,想出算法来不太容易。抛开难度不提,这道题非常非常有意思,老实说这种形式的题目我也是第一次见。

题目链接:https://codeforces.com/contest/1407/problem/C

废话不多说,我们来看题目。

题意

这题是一道非典型的算法题,与其说是一道算法题不如说更像是一个游戏。游戏的目的是猜一个1至n这n个数构成的排列,我们需要通过输入和输出和系统进行交互,从系统处获取更多的信息,最终给出猜测的结果。

首先系统会给定一个整数n,表示这个排列由n个数字构成,这n个数字由前n个正整数构成,也就是1到n这n个数字。之后我们可以通过输出一个命令的形式向系统进行提问,提问的方式是? x y。系统会计算排列当中第x个数对第y个数取模的结果进行返回(排列的下标从1开始),也就是返回

num[x] % num[y] 的值。

系统最多接受2n次询问,当我们已经猜出整个排列之后,输出这个排列。其中n <= 1e4。

样例

非典型算法题,用程序和电脑玩一个游戏

 

这个样例要倒过来看,第一个输入的3表示n。接着就先看输出再看输入。这个样例要猜的结果是[1, 3, 2],首先询问了num[1]对num[2]取余的结果,系统返回是1。接着询问num[3]对num[2]取余的结果,答案是2。接着询问num[1]%num[3]和num[2]%num[1],得到的结果分别是1和0。最终我们根据这些信息猜测出了这个排列是[1, 3, 2],通过! 1 3 2的形式进行返回。

思路

那道题之后我们首先可以发现,n确定了之后这n个数也就确定了。因为n最大,其他数对n取模都是它本身。所以我们需要先找到n的位置。

但是n的位置并不好找,想来想去只有一种办法,就是当出现两个数的余数是n-1的时候,就可以确定这两个数一个是n-1另外一个是n。但是很明显,这样做我们无法在规定步数内解出来。因为n个数两两组合一共有接近n^2种,但是题目限定我们最多只能询问2n次。

很显然,先找到n再寻找其他值是不行的。

既然这个想法不行,我又开始找起了其他方法。我们求了x % y的结果之后,究竟有什么用呢?这个结果到底有没有其他信息呢?

我们来简单分析一下,我们假设x % y = 1,那么这能说明什么吗?很明显,不能说明什么,因为可能性太多了。1对其他数取模都等于1,x % (x-1)也等于1。但假如x % y > (n/2) 呢?其实就能说明问题了。因为x和y的范围是[1, n],现在两个数取模之后的结果大于n的一半,很明显说明x就是这个结果,y是比x更大的数。还有一种情况是x % y = 0,这种情况我们虽然无法确定x和y的值,但是可以知道x一定是y的倍数且x > y。

虽然知道这些,但还是不够解开问题,仍然需要碰运气,因为我们并不能保证在查询次数内刚好就可以找到所有比二分之n大的数。但是这一段分析并不是无用的,我们可以在此基础上更进一步。我们求了x和y的余数之后可以再求一下y和x的余数,假设x % y = a, y % x = b,通过分析a和b我们能够得到什么结果呢?

首先我们可以肯定a和b不会相等,原因也很简单,因为x和y一定不等(排列中的数各不相同)。我们不妨假设x > y,那么y % x =b = y,x % y = a < y。如果a和b相等的话,那么就有 y < y,这显然是不成立的。所以可以肯定a和b一定不等。其次从上面的证明我们也看得出来,在x > y时,那么一定可以得到a < b。因为a = x % y < y,b = y % x = y。也就是说我们可以通过a和b的关系判断x和y的关系,不仅如此,还可以确定y的值。

到这里距离解出这道题已经非常接近了,只差临门一脚,但是这里我还是走了弯路。我当时的想法是把这些数两两配对,这样就可以确定出其中的一半。之后我们再把解不出来的数再进行配对,直到最后只剩下一个数为止。后来发现也有反例,比如[1, 3, 2, 4, 5],在这个例子当中1和3配对,2和4配对,5落单。我们还是没办法解出来。

我在这里苦思冥想了很久,后来才发现答案远在天边近在眼前,解法其实非常简单。我们只需要从前往后遍历维护一个最大值即可。我们假设最大值是id,凡是遇到小于id的数,都可以通过它和id取模的结果求出来。如果遇到了比id更大的数,同样可以通过取模的结果求出id。所以到最后的时候,我们可以求出除了最大值其他的所有数,这个剩下的数就是n。

想通了真的非常非常简单,说穿了一钱不值,但是要靠自己想明白还是不太容易的。并且这道题的题目形式也很新颖,非常非常有趣,适合在周末一玩。

最后,我们来看代码:

import sys


def guess(x, y):
    print('? {} {}'.format(x, y))
    # 输出之后需要flush一下,防止影响输入
    sys.stdout.flush()
    st = input()
    return int(st)


st = input()

n = int(st)
num = [-1 for _ in range(n+2)]

# 一开始将最大值的下标设为1
idx = 1
for i in range(2, n+1):
    x = guess(idx, i)
    y = guess(i, idx)
    # 说明遇到了更大的数,那么x就是之前的最大值
    if x > y:
        num[idx] = x
        idx = i
    # 否则求出来的就是i
    else:
        num[i] = y

num[idx] = n

print('! {}'.format(' '.join(map(str, num[1:n+1]))))

今天的问题到这里就结束了,衷心祝愿大家每天都有所收获。如果还喜欢今天的内容的话,请来一个三连支持吧~(点赞、关注、转发

- END -

 

本文始发于公众号:TechFlow,求个关注



Tags:算法   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
前言Kafka 中有很多延时操作,比如对于耗时的网络请求(比如 Produce 是等待 ISR 副本复制成功)会被封装成 DelayOperation 进行延迟处理操作,防止阻塞 Kafka请求处理线程。Kafka...【详细内容】
2021-12-27  Tags: 算法  点击:(1)  评论:(0)  加入收藏
分稀疏重建和稠密重建两类:稀疏重建:使用RGB相机SLAMOrb-slam,Orb-slam2,orb-slam3:工程地址在: http://webdiis.unizar.es/~raulmur/orbslam/ DSO(Direct Sparse Odometry)因为...【详细内容】
2021-12-23  Tags: 算法  点击:(7)  评论:(0)  加入收藏
一、什么是冒泡排序1.1、文字描述冒泡排序是一种简单的排序算法。它重复地走访要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地...【详细内容】
2021-12-15  Tags: 算法  点击:(16)  评论:(0)  加入收藏
前面文章在谈论分布式唯一ID生成的时候,有提到雪花算法,这一次,我们详细点讲解,只讲它。SnowFlake算法据国家大气研究中心的查尔斯&middot;奈特称,一般的雪花大约由10^19个水分子...【详细内容】
2021-11-17  Tags: 算法  点击:(24)  评论:(0)  加入收藏
基于算法的业务或者说AI的应用在这几年发展得很快。但是,在实际应用的场景中,我们经常会遇到一些非常奇怪的偏差现象。例如,Facebook将黑人标记为灵长类动物、城市图像识别系统...【详细内容】
2021-11-08  Tags: 算法  点击:(32)  评论:(0)  加入收藏
随着注册制的加速推进,新股越来越多,截止到今天A股上市公司的总数高达4500余家,A股一直就是重融资,轻投资的市场,而上市公司发行可转债这种再融资的(圈钱方式)是最能让普通投资者接...【详细内容】
2021-11-05  Tags: 算法  点击:(97)  评论:(0)  加入收藏
导读:在大数据时代,对复杂数据结构中的各数据项进行有效的排序和查找的能力非常重要,因为很多现代算法都需要用到它。在为数据恰当选择排序和查找策略时,需要根据数据的规模和类型进行判断。尽管不同策略最终得到的结果完...【详细内容】
2021-11-04  Tags: 算法  点击:(37)  评论:(0)  加入收藏
这是我在网上找的资源的一个总结,会先给出一个我看了觉得还行的关于算法的讲解,再配上实现的代码: Original author: Bill_Hoo Original Address: http://blog.sina.com.cn/s/bl...【详细内容】
2021-11-04  Tags: 算法  点击:(36)  评论:(0)  加入收藏
每个人都有过这样的经历:打开手机准备回消息或打电话,一看到微信图标右上方的小红点,于是忍不住先打开微信;看完微信,不知不觉又被另一个App牵引,直到关闭手机屏幕才发现自己早已...【详细内容】
2021-11-03  Tags: 算法  点击:(30)  评论:(0)  加入收藏
文丨互联网怪盗团在互联网行业,尤其是在投资人心目中,往往存在一种“算法迷信”或曰“技术迷信”:某公司的广告变现做得好,一定是因为有算法;某公司的云计算业务开展的好,也是因为...【详细内容】
2021-11-03  Tags: 算法  点击:(25)  评论:(0)  加入收藏
▌简易百科推荐
前言Kafka 中有很多延时操作,比如对于耗时的网络请求(比如 Produce 是等待 ISR 副本复制成功)会被封装成 DelayOperation 进行延迟处理操作,防止阻塞 Kafka请求处理线程。Kafka...【详细内容】
2021-12-27  Java技术那些事    Tags:时间轮   点击:(1)  评论:(0)  加入收藏
博雯 发自 凹非寺量子位 报道 | 公众号 QbitAI在炼丹过程中,为了减少训练所需资源,MLer有时会将大型复杂的大模型“蒸馏”为较小的模型,同时还要保证与压缩前相当的结果。这就...【详细内容】
2021-12-24  量子位    Tags:蒸馏法   点击:(9)  评论:(0)  加入收藏
分稀疏重建和稠密重建两类:稀疏重建:使用RGB相机SLAMOrb-slam,Orb-slam2,orb-slam3:工程地址在: http://webdiis.unizar.es/~raulmur/orbslam/ DSO(Direct Sparse Odometry)因为...【详细内容】
2021-12-23  老师明明可以靠颜值    Tags:算法   点击:(7)  评论:(0)  加入收藏
1. 基本概念希尔排序又叫递减增量排序算法,它是在直接插入排序算法的基础上进行改进而来的,综合来说它的效率肯定是要高于直接插入排序算法的;希尔排序是一种不稳定的排序算法...【详细内容】
2021-12-22  青石野草    Tags:希尔排序   点击:(6)  评论:(0)  加入收藏
ROP是一种技巧,我们对execve函数进行拼凑来进行system /bin/sh。栈迁移的特征是溢出0x10个字符,在本次getshell中,还碰到了如何利用printf函数来进行canary的泄露。ROP+栈迁移...【详细内容】
2021-12-15  星云博创    Tags:栈迁移   点击:(19)  评论:(0)  加入收藏
一、什么是冒泡排序1.1、文字描述冒泡排序是一种简单的排序算法。它重复地走访要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地...【详细内容】
2021-12-15    晓掌柜丶韶华  Tags:排序算法   点击:(16)  评论:(0)  加入收藏
在了解golang的map之前,我们需要了解哈希这个概念。哈希表,又称散列表(Hash table),是根据键(key)而直接访问在内存储存位置的数据结构。也就是说,它通过计算出一个键值的函数,将...【详细内容】
2021-12-07  一棵梧桐木    Tags:哈希表   点击:(13)  评论:(0)  加入收藏
前面文章在谈论分布式唯一ID生成的时候,有提到雪花算法,这一次,我们详细点讲解,只讲它。SnowFlake算法据国家大气研究中心的查尔斯&middot;奈特称,一般的雪花大约由10^19个水分子...【详细内容】
2021-11-17  小心程序猿QAQ    Tags:雪花算法   点击:(24)  评论:(0)  加入收藏
导读:在大数据时代,对复杂数据结构中的各数据项进行有效的排序和查找的能力非常重要,因为很多现代算法都需要用到它。在为数据恰当选择排序和查找策略时,需要根据数据的规模和类型进行判断。尽管不同策略最终得到的结果完...【详细内容】
2021-11-04  华章科技    Tags:排序算法   点击:(37)  评论:(0)  加入收藏
这是我在网上找的资源的一个总结,会先给出一个我看了觉得还行的关于算法的讲解,再配上实现的代码: Original author: Bill_Hoo Original Address: http://blog.sina.com.cn/s/bl...【详细内容】
2021-11-04  有AI野心的电工和码农    Tags: KMP算法   点击:(36)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条