トピック:
分析:
デジタル入力周波数はこの質問には、例えば、入力され得る複数回表示されます:1223345(タイトルの別のサンプルではなく、切り取っスクリーンショットで)、我々はNUMを使用することができます[105]配列は、回数に現れるが、NUMは、最初の行の配列データに格納されている数を記憶するために、2行目の入力データは、単に最初のデジタル選択、我々は店に配列AA [105]を使用して得ることができ表します。AA各アレイ素子AAを介して後周期アレイ、でソート要素、これに基づいて把握することが可能と上部手を表し、このFLAC場合、使用は、エスケープの数を決定することができるDFS優勝状態中に発生した、この時間は失敗する運命にある上側の手は、それが毎回フリップフロッ勝てば、その後、上側の手は、真の性能のリターンを獲得することで、偽のDFSリターンを示しました。
コード:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int MAXN = 105;
//num数组用于存放第一行输入的每一个数的出现次数 aa数组用于存放第二行先手可以先出的牌数
int num[MAXN],aa[MAXN];
vector<int> vec[MAXN]; //vec[i]用于存放在1和100之间并且在num数组中出现过的i的约数或者倍数
int ind;
bool Select(int k)
{
//这里必须要从vec[k].size()开始,如果从0开始会出现超时(这里不懂为啥超时。。。)
for(int i=vec[k].size()-1;i>=0;--i)
if(num[vec[k][i]])
{
num[vec[k][i]]--;
bool ok = Select(vec[k][i]);
num[vec[k][i]]++;
if(ok) return false;
}
return true;
}
int main()
{
int x;
while(true)
{
cin >> x;
num[x]++;
char ch = getchar();
if(ch == '\n') break;
}
while(true)
{
cin >> x;
aa[++ind] = x;
char ch = getchar();
if(ch == '\n') break;
}
//对aa数组排序,因为如果先手有必胜态,题目要求的是输出能产生必胜态的最小的数字
sort(aa+1,aa+ind+1);
//下面的循环两层必须都从1到100循环,因为不管是先手还是后手,拿到一张牌之后,都要依据vec来
//寻找此数的约数或是倍数。
for(int i=1;i<=100;++i)
for(int j=1;j<=100;++j)
if((i%j==0||j%i==0)&&num[j])
vec[i].push_back(j);
for(int i=1;i<=ind;++i)
{
if(num[aa[i]])
{
num[aa[i]]--; //此处表示先出首先出了aa[i]这张牌
//如果Select(aa[i])返回true,那么说明后手不管出了什么牌,都是必败的,那么此时就可以输出
//aa[i]并且结束程序
if(Select(aa[i]))
{
printf("%d\n",aa[i]);
return 0;
}
num[aa[i]]++; //回溯 这里表示先出aa[i]是必败的,那么判断下一种情况
}
}
printf("-1\n");
return 0;
}