Interpretations P2741 [[USACO4.4] Frame Up superimposed image]

Topic Portal
This problem a few days before NOIP2018 be used when we coach PJ confidence season T3

Thinking readily occur, since each part of each side of the rectangle are exposed, it is only necessary to record each letter x, y coordinates of the maximum value, the minimum value can be determined for each rectangle, which can then be launched cover letter what letter.

Then it is how to find a situation, at the beginning I chose the method most violent, enumerate all permutations, if not the letter covering the relationship exits.

Code:

// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
int jx[26][4],ss;//jx记录每个矩形的四个角,ss记录字母的种数
bool b[26][26];//b[i][j]表示字母j覆盖了字母i
bool bbb[26];//bbb[i]表示字母i是否出现过
void dfs(string s)
{
    if(s.size()==ss){cout<<s<<endl;return;}//如果枚举完了就输出
    for(int i=0;i<26;i++)//枚举每种字母
    {
        if(!bbb[i])continue;//如果字母i没出现过就continue
        bool bb=1;
        for(int j=0;j<s.size();j++)
        {
            if(b[i][s[j]-'A']){bb=0;break;}//如果不满足覆盖关系就退出
        }
        if(bb){bbb[i]=0;dfs(s+char(i+'A'));bbb[i]=1;}//如果满足覆盖关系就往下dfs
    }
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    string s[n];
    for(int i=0;i<n;i++)cin>>s[i];
    for(int k=0;k<26;k++)jx[k][1]=jx[k][3]=999;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            if(s[i][j]!='.')
            {
                int kkk=s[i][j]-'A';
                bbb[kkk]=1;
                jx[kkk][0]=max(jx[kkk][0],i);//记录每个矩形的四角
                jx[kkk][1]=min(jx[kkk][1],i);
                jx[kkk][2]=max(jx[kkk][2],j);
                jx[kkk][3]=min(jx[kkk][3],j);
            }
        }
    }
    for(int i=0;i<n;i++)for(int j=0;j<m;j++)for(int k=0;k<26;k++)if(bbb[k] && (((i==jx[k][0] || i==jx[k][1]) && j<=jx[k][2] && j>=jx[k][3]) || ((j==jx[k][2] || j==jx[k][3]) && i<=jx[k][0] && i>=jx[k][1])))b[k][s[i][j]-'A']=1;//记录覆盖关系
    for(int i=0;i<26;i++)if(bbb[i])ss++;
    dfs("");
}

Last point a tragic TLE.

Then change the thinking, because it is known which of the following letters in the alphabet which, it is conceivable to use topological sort, so they the AC.

Code:

// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
int jx[26][4],ss,kkk,n,m,rd[26];//变量都一样,rd[i]表示字母i的入度
bool b[26][26],bbb[26];
char sss[26];
inline void dfs(int l)//拓扑排序(懒得改函数名了)
{
    if(l==ss){printf("%s\n",sss);return;}
    for(register int i=0;i<26;++i)
    {
        if(!bbb[i])continue;//如果字母i没出现过就continue
        if(rd[i]==0)//如果字母i的入度等于0就进行拓扑排序
        {
            for(register int j=0;j<26;j++)
            {
                if(b[i][j])rd[j]--;//将所有覆盖当前字母的入度减1
            }
            sss[l]=i+'A';
            bbb[i]=0;
            dfs(l+1);//往下dfs
            bbb[i]=1;
            for(register int j=0;j<26;j++)
            {
                if(b[i][j])rd[j]++;//进行还原
            }
        }
    }
}
int main()//都一样
{
    int i,j,k;
    scanf("%d%d\n",&n,&m);
    char s[n][m];
    for(i=0;i<n;++i)scanf("%s",s[i]);
    for(k=0;k<26;++k)jx[k][1]=jx[k][3]=999;
    for(i=0;i<n;++i)
    {
        for(j=0;j<m;++j)
        {
            if(s[i][j]!='.')
            {
                kkk=s[i][j]-'A';
                bbb[kkk]=1;
                jx[kkk][0]=max(jx[kkk][0],i);
                jx[kkk][1]=min(jx[kkk][1],i);
                jx[kkk][2]=max(jx[kkk][2],j);
                jx[kkk][3]=min(jx[kkk][3],j);
            }
        }
    }
    for(i=0;i<n;++i)for(j=0;j<m;++j)for(k=0;k<26;++k)if(k!=s[i][j]-'A' && !b[k][s[i][j]-'A'] && bbb[k] && (((i==jx[k][0] || i==jx[k][1]) && j<=jx[k][2] && j>=jx[k][3]) || ((j==jx[k][2] || j==jx[k][3]) && i<=jx[k][0] && i>=jx[k][1])))
    {b[k][s[i][j]-'A']=1;rd[s[i][j]-'A']++;}//如果字母k在字母s[i][j]-'A'下面就将字母s[i][j]-'A'的入度加1
    for(i=0;i<26;++i)if(bbb[i])++ss;
    dfs(0);
}

Guess you like

Origin www.cnblogs.com/pzc2004/p/11600853.html