您的位置:首页 > 其它

历届试题 约数倍数选卡片 博弈论?dfs

2017-04-06 22:47 453 查看
问题描述

  闲暇时,福尔摩斯和华生玩一个游戏:

  在N张卡片上写有N个整数。两人轮流拿走一张卡片。要求下一个人拿的数字一定是前一个人拿的数字的约数或倍数。例如,某次福尔摩斯拿走的卡片上写着数字“6”,则接下来华生可以拿的数字包括:

  1,2,3, 6,12,18,24 ....

  当轮到某一方拿卡片时,没有满足要求的卡片可选,则该方为输方。

  请你利用计算机的优势计算一下,在已知所有卡片上的数字和可选哪些数字的条件下,怎样选择才能保证必胜!

  当选多个数字都可以必胜时,输出其中最小的数字。如果无论如何都会输,则输出-1。

输入格式

  输入数据为2行。第一行是若干空格分开的整数(每个整数介于1~100间),表示当前剩余的所有卡片。

  第二行也是若干空格分开的整数,表示可以选的数字。当然,第二行的数字必须完全包含在第一行的数字中。

输出格式

  程序则输出必胜的招法!!

样例输入

2 3 6

3 6

样例输出

3

样例输入

1 2 2 3 3 4 5

3 4 5

样例输出

4

#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
int a[12000],b[12000],vis[12000],n,m;
vector<int> g[12000];
bool dfs(int i){
vis[i]=1;
for(int j=g[i].size()-1;j>=0;j--)
if(!vis[g[i][j]]){
// vis[j]=1;
if(dfs(g[i][j]))
{
vis[i]=0;
return false;
}
// vis[j]=0;;
}
vis[i]=0;
return true;
}
int main(){
while(~scanf("%d",a+n)){
for(int i=0;i<n;i++)
if(a[i]%a
==0||a
%a[i]==0){
g[i].push_back(n);
g
.push_back(i);
}
n++;
if(getchar()=='\n')
break;
}
while(~scanf("%d",b+m)){
m++;
if(getchar()=='\n')
break;
}
for(int i=0;i<m;i++){
// memset(vis,0,sizeof(vis));
for(int j=0;j<n;j++)
if(b[i]==a[j]){
// vis[j]=1;
if(dfs(j)){
cout<<a[j]<<endl;
return 0;
}
}
}
cout<<-1<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: