PTA_2021年团体程序设计天梯赛_总决赛_L3-2 还原文件 (30 分)_dfs+回溯

//
输出格式:
在一行中输出还原后纸条的正确拼接顺序。纸条编号间以一个空格分隔,行首尾不得有多余空格。

题目数据保证存在唯一解。

输入样例:
17
95 70 80 97 97 68 58 58 80 72 88 81 81 68 68 60 80
6
4 68 58 58 80
3 81 68 68
3 95 70 80
3 68 60 80
5 80 72 88 81 81
4 80 97 97 68
输出样例:
3 6 1 5 2 4

// L3-2 还原文件 (30 分)
#include<bits/stdc++.h>
using namespace std;

const int M=111;
bool used[M];

vector<int> judge,chip[M];
vector<int> v,ans;

int n,m,flag;

void dfs( int len )	
{						// ans=v; 因为 return 后会删除尾元素 
    if( len>=n-1 ) { ans=v; flag=1; return ; }
    if( flag ) return ;

    int i,j;
    for( i=1;i<=m;i++ )     // m
    {
        if( used[i]==0 )
        {
            for( j=0;j<chip[i].size();j++ )
            {
                if( chip[i][j] != judge[len+j] ) break;
            }
            if( j==chip[i].size() )
            {								
                used[i]=1; v.push_back( i ); 
                dfs( len+j-1 );             // chip[i].size()-1
                used[i]=0; v.pop_back();
            }
        }		// 注意到可能会出现缺口匹配不唯一的情况 ( 部分缺口一致 ), dfs 需要回溯. 
    }
}

void init()
{
    memset( used,0,sizeof( used ) );
    for( int i=0;i<M;i++ ) chip[i].clear();
    judge.clear();
    ans.clear();
    v.clear();
    flag=0;
}

int main()
{
    int i,k,x;

    while( cin>>n )
    {
        init();
        for( i=0;i<n;i++ ) { cin>>x; judge.push_back( x ); }

        cin>>m;
        for( i=1;i<=m;i++ )     //  i(1≤i≤M)
        {
            cin>>k;
            while( k-- ) { cin>>x; chip[i].push_back( x ); }
        }
        dfs(0);

        for( i=0;i<ans.size();i++ )
        {
            if(i) cout<<' ';
            cout<<ans[i];
        }
        cout<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_63173957/article/details/123695078