UCF Local Programming Contest 2018-F

 Team Shirts/Jerseys

题意:给你n个数,然后你随便选一个数(1~99),问你这n+1个数是否可以拼接成给定得数字

解释:dfs,注释在代码中给出。

链接:https://nanti.jisuanke.com/t/44152

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e2+10;
typedef long long ll;
ll str;
ll n,len,a[maxn],b[maxn],c[maxn];
ll vis[maxn];
void init()
{
    cin>>str>>n;
    ll temp=str;
    while(temp)
    {
        len++;
        temp/=10;
    }
    for(int i=len-1;i>=0;i--)
    {
        a[i]=str%10; //先把str换成数组保存 
        str/=10;
    } 
    for(int i=0;i<n;i++)
    {
        cin>>temp;
        b[i]=temp/10;
        c[i]=temp%10; //分解每一个数得十位和个位 
    }
}
ll dfs(ll pos,ll flag) //pos表示当前dfs到哪个为止,flag表示是否使用了特殊数字 
{
    if(pos==len) return 1; // 成功得到答案 
    if(pos>len||a[pos]==0) return 0; //如果超出数字范围,或者遍历位置是0(不会出现前导0der) 
    if(flag==0&&(dfs(pos+1,1)||dfs(pos+2,1))) return 1; //使用特殊数字,跳过一位或者两位 
    for(int i=0;i<n;i++)
    {
        if(!vis[i])
        {
            int t=0;
            for(int j=0;j<i;j++)
            {
                if(!vis[j]&&b[j]==b[i]&&c[j]==c[i])
                {
                    t=1;
                    break;
                }
            }
            /*上面的for是剪枝效果,如果我当前
            之前已经遍历过和我相同地数字,而且没又
            采用,这这次必不可能采用*/ 
            if(t) continue;
            if(b[i]==0) //下面就是很常规的判断了 
            {
                if(c[i]==a[pos])
                {
                    vis[i]=1;
                    if(dfs(pos+1,flag)) return 1;
                    vis[i]=0;
                }
            }
            else if(pos+1<len)
            {
                if(b[i]==a[pos]&&c[i]==a[pos+1])
                {
                    vis[i]=1;
                    if(dfs(pos+2,flag)) return 1;
                    vis[i]=0;
                }
            }
        }
    }
    return 0;
}
int main()
{
std::ios::sync_with_stdio(false);
init();
cout<<dfs(0,0)<<endl;
return 0;
}
 
原文地址:https://www.cnblogs.com/tombraider-shadow/p/12628206.html