奇偶游戏

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

奇偶游戏

不时地,你和你的朋友玩下列游戏:你的朋友写下一个由许多“1”和“0”组成的数字序列。你从中选一个连续的子序列(假如这个序列从第3个数字开始到第5个数字,包含3,5在内),并问他这个序列中所含的“1”的个数是奇数还是偶数。你的朋友回答了你的这个问题。你可能接着问他另一个子序列如此之类的问题。你的任务是猜测整个数字序列。

你怀疑你的朋友的某些答案不正确,并且你想证实他在撒谎。因此你决定编一个程序来帮你判断,该程序将接收到一系列你所提的问题以及从你的朋友处获得的回答,该程序的目的是为了找到第一个可能错误的回答:即存在某个序列,能满足以前的所有问题的回答,但不存在任何一个序列能满足当前的回答。

输入:

输入文件PARITY.IN的首行包括一个数,代表0和1序列的长度,该长度小于等于1000000000。在第二行,有一个正整数,代表问题以及它们的回答的个数,此数要小于等于5000。剩下的行具体阐述问题和回答。每行包括一个问题和对它的回答:2个整数(选中子序列中第一个和最后一个数字的位置)和一个单词,即“EVEN”或是“ODD”(这个回答就是“1”在该选中序列中的数量的奇偶性,‘EVEN’表示偶数,‘ODD’表示奇数)。

输出:

在输出文件PARITY.OUT中仅有一行,包括一个整数X。数字X表示存在满足前X个奇偶条件的某一序列,但不存在序列能满足前X+1个条件。如果存在一个序列的个数能满足所有给出的条件,那么X就是所问的全部问题的个数。

例子1:

PARITY.IN:

10

5

1 2 EVEN

3 4 ODD

5 6 EVEN

1 6 EVEN

7 10 ODD

PARITY.OUT:

3

例子2:

PARITY.IN:

10

5

1 2 EVEN

1 4 EVEN

2 4 ODD

1 10 EVEN

3 10 EVEN

PARITY.OUT:

5

分析:

初看本题,有些摸不着头脑的感觉,好像只有用搜索去找出所有符合前x-1(不定)个回答的序列,再一一证明它们均不可能符合第x个回答,然后输出x,但这个算法是极其低效的,根本不可能符合题目的时、空要求,必须另辟蹊径。再仔细看看题目规定的数据规模:01序列的长度小于等于1000000000;问题以及它们的回答的个数小于等于5000。这似乎在提示我们换一个角度思考,即,从那5000个问题入手可能会使问题简单一些。我们可以将读入的一个个问答都保存下来,若当前的问答涉及的数列范围与

保存过的问答间有联系,即可进行进一步处理:若两者涉及的范围一模一样,

则可直接判断它们是否矛盾,若矛盾则可直接输出结果,否则处理下一个问答;若两者在边界上相邻,则将它们合并,且删去旧的序列,新序列的奇偶性由两者的奇偶性进行异或运算得到(证明

如下:假设两者的奇偶性分别为s1、s2,新序列的奇偶性为s3(奇数为1;偶数为0),则根据奇+奇=偶、奇+偶=奇、偶+偶=偶可得:若s1=奇,s2=奇,则s3=s1 xor s2=1 xor 1=0=偶;若s1=偶,s2=奇,则s3=s1 xor s2=0 xor 1=1=奇;若s1=偶,s2=偶,则s3= s1 xor s2=0 xor 0=0=偶。故得证)。若所有问答都处理完了仍无矛盾,则输出问答总数。考虑到算法涉及数列中的删除,故用链表存储(见parity’.pas)。但在以上算法中查找问答之间的关系十分费时,难以满足题目的时限要求,还得继续优化。首先,序列可以按照问答涉及的数据范围的大小排序,起点小的在前,起点相同时终点小的在前。其次,对于当前输入的问答,找出保存过的问答中与它起点相同的问答,若终点也相同则按上文叙述的处理,否则将二者相同的部分删去,即将终点较小的问答删去,终点较大的问答只保留后一部分,它的奇偶性也由异或运算求得,这么做与上文叙述的将问答合并的原理是相同的,但操作后剩余的问答数目却少得多(合并时两端关联的都要处理),使算法优化了不少。至于最终的数据结构,综合考虑有序数列的查找、不同数据结构的操作速度、编程复杂度和程序可读性等,还是用数组比较合适(见parity.pas)。

相关文档
最新文档