L1-071 前世档案(分数20)
输入格式
第一行给出两个正整数n ,m;n表示问题的数量,m表示回答的人数
随后m行,每个人对于每个问题做出“yes”或“no”的回答,用 y 与 n表示,
对于回答的顺序,最后做出其对应的结论
输入样例
3 4
yny
nyy
nyn
yyn
输出样例
3
5
6
2
其关系图如下图所示

解题思路
这是一个满二叉树,我们发现,选择y就是选择走左子树,选择n就是走右子树。假如对于某个节点,我们面临选择,此时我们可走到的叶节点的范围是[l,r]
如果我们选择y,我们的范围就会变成[l,(l+r)/2];
如果我们选择l,我们的范围就会变成[(l+r)/2+1,r];
显然可以根据这个逻辑轻松写出代码。
其实有一个结论
把y当成0,把n当成1,就形成了一个二进制数,比如ynn 变成了 011 , 再转换为十进制,就变成了 1 * 2^0 + 1 * 2^1 + 0 * 2^2 = 3,因为
二进制转换为十进制从0开始,所以再加一就是正确答案。
题解
#include<iostream>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
int range = 1;
for(int i = 0 ; i < n ; i++) range *= 2;
while(m--)
{
string s;cin>>s;
int l = 1 , r = range;
for(char c : s)
{
int mid = (l + r) / 2;
if(c == 'y') r = mid;
else l = mid + 1;
}
cout<<l<<endl;
}
return 0;
}

浙公网安备 33010602011771号