1 条题解

  • 0
    @ 2025-8-24 22:40:39

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar XIxii
    Cease to struggle and you cease to live. ---Thomas Carlyle.

    搬运于2025-08-24 22:40:39,当前版本为作者最后更新于2023-10-04 10:15:29,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    思路:

    aia_{i} 表示有几个数字 ii 可以选择,当 aia_{i} 等于时表示已经不能选择数字 ii 了。用数组 bib_{i} 存储 lenb 个输入第二行的 可选的数字 。vecivec_{i} 存储数字 ii 在当前卡片中的所有倍数和约数。

    对可选的数字从小到大依次进行一次深度搜索,如果返回 true 表示此数字可以选择,输出该数字并结束程序。深度搜索函数带有参数 numnumtt。其中,numnum 表示当前最新已选择的数,tt 表示当前已选择数 numnum 的是自己还是对手,11 表示是自己,此时轮到了对手选择了。00 表示是对手,此时轮到了自己选择了。如果当前是自己,那么就是 11 。自己赢的条件是 numnum 的所有约数倍数都不可选,返回 true。如果当前是对手,就是 00,则自己只要有一个选择是可以赢的那么自己就是赢了。

    如果还有不理解的地方,可以参考代码及注释。

    关于这道题的难度,大概是绿题左右吧。

    代码:

    #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;
    } 
    
    • 1

    信息

    ID
    5924
    时间
    1000ms
    内存
    128MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者