P8609 [蓝桥杯 2013 国 A] 约数倍数选卡片 题解
思路:
用
对可选的数字从小到大依次进行一次深度搜索,如果返回 true 表示此数字可以选择,输出该数字并结束程序。深度搜索函数带有参数
如果还有不理解的地方,可以参考代码及注释。
关于这道题的难度,大概是绿题左右吧。
代码:
#include <bits/stdc++.h>
using namespace std;
int a[110],b[110];
int lena,lenb,maxx;
vector<int> vec[110];
bool dfs(int num,int t)
{
int k,i;
a[num]--;
for(i=vec[num].size()-1;i>=0;i--) //这里是要从大到小搜索,可以尝试一下从小到大搜索体会体会差距
{
if(a[vec[num][i]]>0)
{
if(t==1 && !dfs(vec[num][i],1-t)) //当前是自己选,对手任何选择都是输自己才是赢 ,对手有一个选择是赢的自己就输
{
a[num]++;
return false;
}
else if(t==0 && dfs(vec[num][i],1-t))// 当前是对手,自己只要有一个选择是可以赢的就是赢
{
a[num]++;
return true;
}
}
}
a[num]++;
if(t==1)
{
return true;
}
else
{
return false;
}
}
int main()
{
int i,j,temp=0;
string first,second;
getline(cin,first);
getline(cin,second);
for(i=0;i<first.size();i++) //将输入第一行的字符串中的数一个个提取出,并保存为int型
{
if(first[i]<='9' && first[i]>='0')
{
temp=temp*10+first[i]-'0';
if(first[i+1]>'9' || first[i+1]<'0') //这是这个数的个位,下一个字符是分隔两个数的
{
lena++;
a[temp]++;
temp=0;
}
}
}
for(i=0;i<second.size();i++) //将输入第一行的字符串中的数一个个提取出,并保存为int型
{
if(second[i]<='9' && second[i]>='0')
{
b[lenb]=b[lenb]*10+second[i]-'0';
if(second[i+1]>'9' || second[i+1]<'0')//这是这个数的个位,下一个字符是分隔两个数的
{
lenb++;
}
}
}
sort(b,b+lenb);//从小到大排列
//将每个数的约数和倍数先存入
for(i=1;i<=100;i++)
{
if(a[i]>0)
{
for(j=1;j<=100;j++)
{
if(a[j]>0 && (j%i==0 || i%j==0))
{
vec[i].push_back(j);
}
}
}
}
for(i=0;i<lenb;i++)
{
if(dfs(b[i],1))//参数1表示自己,0表示对手,如果返回值为true,表示找到方法
{
cout<<b[i]<<endl;
return 0;
}
}
cout<<-1<<endl;
return 0;
}