【题目描述】
有一个集合M是这样生成的:(1) 已知k是集合M的元素; (2) 如果y是M的元素,那么,2y+1和3y+1都是M的元素;(3) 除了上述二种情况外,没有别的数能够成为M的一个元素。
问题:任意给定k和x,请判断x是否是M的元素。这里的k是无符号整数,x 不大于 100000,如果是,则输出YES,否则,输出NO。
【输入】
输入整数 k 和 x, 逗号间隔。
【输出】
如果是,则输出 YES,否则,输出NO。
【输入样例】
0,22
【输出样例】
YES
解题思路:倒推法
假设x是集合中的元素,则(x-1)/2或(x-1)/3必然是集合中的元素。
用t记录(x-1)/2或(x-1)/3的值,则(t-1)/2或(t-1)/3则必然是集合中的元素
每次判断t是否和x相等就行了,如果有一个t和x相等,则x是由k产生的集合中的元素
如果t<x了,则x不是集合中的元素
如果t不能继续倒推了,即(t-1)%2!=0并且(t-1)%3!=0,都不能整除,则x不是集合中的元素
如果(t-1)%2余数为0,则继续对(t-1)/2的得数继续倒推
如果(t-1)%3余数为0,则继续对(t-1)/3的得数继续倒推
#include<iostream>
using namespace std;
bool yes=false; //yes记录x是否为M的元素,默认为否
int k,x;
char c;//用来接收输入的逗号
bool dfs(int x)
{
int t,t2;
t2=x;
if(t2<k) //比如k=3,x=2;
{
yes=false;
return false;
}
if(t2==k) //x=k,x当然是集合的元素了
{
yes=true;
return true;
}
else
{
t=t2-1;
if(t%2!=0&&t%3!=0)//比如开始输入k=2,x=6;k=2产生的集合为{2,5,7,11,15,16,22,……} t=5,不好继续倒推了
{
yes=false;
return false;
}
else //t%2==0或t%3==0s
{
bool tt2=false;
bool tt3=false;
if(t%2==0)//x=2y+1,y=(x-1)/2
{
tt2=dfs(t/2);
}
if(t%3==0)x=3y+1,y=(x-1)/3
{
tt3=dfs(t/3);
}
if(tt2||tt3)
return true;
else
return false;
}
}
}
int main()
{
cin>>k>>c>>x;
if(dfs(x))
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
return 0;
}