• UVa 502 DEL command


    题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=443

    这题刚开始看的时候小郁闷了一下,入门经典把它放在难回溯的分类里,可我怎么也没觉得它跟回溯有啥关系,于是搁置了很久。

    题意:-是需要删除的文件,+是需要保留的文件,构造一个字符串,使它能一步删除所有需要删除的文件,同时不会误删需要保留的文件。

    思路:遍历所有需要删除的文件,相同位置字母相同的话,就填充那个字母,否则填充'?',最后长度不匹配补'*'。构造完成后,验证是否会删掉需要保留的文件。

    测试数据参考:http://hi.baidu.com/zyz913614263/item/7bd90a4474cd82f7bcf45166

    不过因为百度空间把空格跟弄没了,我也不知道学长那组数据是怎么分的,于是我根据自己的理解又重新分了一下:

    INPUT

    9

    -A
    -AA
    -AAA
    +AAAA

    -AAA
    -AAAA
    +AA

    -AB
    -AA
    +AAAA

    -AB
    -BB
    +ABAA

    -X.A
    -X.AA
    +X.AAA

    -X.AB
    -X.AA
    +X.AAA

    -X.AB
    -X.BB
    +X.ABA

    -X.A
    -X.AA
    +X
    -X.AA
    -X.AAA
    +X.A

    -X.AB
    -X.BB
    +X.ABA
    -X.A

    OUTPUT:

    IMPOSSIBLE

    DEL AAA*.

    DEL A?.

    DEL ?B.

    IMPOSSIBLE

    DEL X.A?

    DEL X.?B

    IMPOSSIBLE

    IMPOSSIBLE

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    
    const int MAXN = 1010;
    
    struct node
    {
        char ch;     //保留还是删除
        char name[10];    //文件名
        char tuozhan[5];   //拓展名
        int len1, len2;   //len1 - 文件名串长度 len2 - 拓展名串长度
    };
    
    node D[MAXN];
    char ans[100];   //答案文件名
    char ansT[10];   //答案拓展名
    int anslen, ansTlen;   //答案文件名长度,答案拓展名长度
    int N;        //全部文件个数
    int jian;     //需要删除的文件个数
    int minLen;    //需要删除的文件中文件名的最小长度
    int tuozhanMinLen;   //需要删除的文件中拓展名的最小长度
    bool lenflag;     //需要删除的文件中,文件名是否有跟最小长度不等长的
    bool tuozhanlenflag;   //需要删除的文件中,拓展名是否有跟最小长度不等长的
    
    int cmp( const void *a, const void *b )   //排序,需要删除的文件排在前,保留的排在后
    {
        node *c = ( node *)a;
        node *d = ( node *)b;
        return d->ch - c->ch;
    }
    
    bool check()    //检查是否会删掉需要保留的文件
    {
        bool flag = true;
        for ( int i = jian; flag && i < N; ++i )
        {
            flag = false;   //可以删
            for ( int j = 0; j < minLen && j < D[i].len1; ++j )
            {
                if ( ans[j] == '?' ) continue;
                if ( D[i].name[j] != ans[j] )   // 若有字符不同
                {
                    flag = true;   //不可删
                    break;
                }
            }
    
            if ( !flag )   //检验长度是否符合
            {
                if ( ans[anslen - 1] == '*' )
                {
                    if ( anslen - 1 > D[i].len1 ) flag = true;
                }
                else if ( anslen != D[i].len1 ) flag = true;
            }
    
            if ( !flag )  //如果文件名可删,再检查拓展名
            {
                for ( int j = 0; j < tuozhanMinLen && j < D[i].len2; ++j )
                {
                    if ( ansT[j] == '?' ) continue;
                    if ( D[i].tuozhan[j] != ansT[j] )   //存在不同字符
                    {
                        flag = true;    //不可删
                        break;
                    }
                }
    
                if ( !flag )   //检验长度是否符合
                {
                    if ( ansT[ ansTlen - 1 ] == '*' )
                    {
                        //printf( "%d %d\n", D[i].len2, ansTlen - 1 );
                        if ( D[i].len2 < ansTlen - 1  ) flag = true;
                    }
                    else if ( ansTlen != D[i].len2 ) flag = true;
                }
            }
        }
        if ( flag ) return true;
        else return false;
    }
    
    void solved( )  //构造答案
    {
        for ( int i = 0; i < minLen; ++i )
        {
            bool flag = true;
            for ( int j = 1; j < jian; ++j )
            {
                if ( D[j].name[i] != D[j - 1].name[i] )
                {
                    flag = false;
                    break;
                }
            }
            if ( flag ) ans[i] = D[0].name[i];
            else ans[i] = '?';
        }
        int len = minLen;
        if ( lenflag ) ans[len++] = '*';
        ans[len++] = '.';
        ans[len] = '\0';
        //puts(ans);
        anslen = len - 1;
    
    
        for ( int i = 0; i < tuozhanMinLen; ++i )
        {
            bool flag = true;
            for ( int j = 1; j < jian; ++j )
            {
                if ( D[j].tuozhan[i] != D[j - 1].tuozhan[i] )
                {
                    flag = false;
                    break;
                }
            }
            if ( flag ) ansT[i] = D[0].tuozhan[i];
            else ansT[i] = '?';
        }
        len = tuozhanMinLen;
        if ( tuozhanlenflag ) ansT[ len++ ] = '*';
        ansT[ len ] = '\0';
        //puts(ansT);
        ansTlen = len;
    
        if ( check() ) printf( "DEL %s%s\n", ans, ansT );
        else puts("IMPOSSIBLE");
    
        return;
    }
    
    int main()
    {
        int T;
        char temp[50];
        scanf( "%d", &T );
        getchar();
        getchar();
        while ( T-- )
        {
            memset( D, '\0', sizeof(D) );
            N = 0;
            minLen = 1000;
            tuozhanMinLen = 100;
            lenflag = false;
            tuozhanlenflag = false;
            while ( gets( temp ) != NULL && temp[0] != '\0' )
            {
                D[N].ch = temp[0];
    
                int i = 1, j = 0;
                int len = strlen(temp);
    
                while ( i < len && temp[i] != '.' )   //提取文件名
                    D[N].name[j++] = temp[i++];
                D[N].name[j] = '\0';
                D[N].len1 = j;
                if ( D[N].ch == '-' )
                {
                    if ( j < minLen ) minLen = j;
                    //if ( j != minLen ) lenflag = true;
                }
    
                j = 0;++i;
                while ( i < len )    //提取拓展名
                    D[N].tuozhan[j++] = temp[i++];
                D[N].tuozhan[j] = '\0';
                D[N].len2 = j;
                if ( D[N].ch == '-' )
                {
                    if ( j < tuozhanMinLen ) tuozhanMinLen = j;
                    //if ( j != tuozhanMinLen ) tuozhanlenflag = true;
                }
                ++N;
            }
    
            qsort( D, N, sizeof(D[0]), cmp );
    
            jian = 0;
            for ( int i = 0; i < N; ++i )
            {
                //printf( "%s %s\n", D[i].name, D[i].tuozhan );
                if ( D[i].ch == '+' ) break;
                if ( D[i].len1 != minLen ) lenflag = true;
                if ( D[i].len2 != tuozhanMinLen ) tuozhanlenflag = true;
                ++jian;
            }
            //printf( "%d %d\n", N, jian );
            memset( ans, '\0', sizeof(ans) );
            solved();
            if (T) puts("");   //两组数据之间输出一个空行
        }
        return 0;
    }
  • 相关阅读:
    Mac OS X:在VirtualBox中使用Xcode连接IPAD
    Xcode:PhoneGap 2.5.0项目创建方法
    Android:网络操作2.3等低版本正常,4.0(ICS)以上出错,换用AsyncTask异步线程get json
    安卓:WebView中iframe,焦点字段出现两个文本输入框,位置错误
    Mac OS X:Mac系统鼠标滚轮方向调整
    Xcode:missing file xxx
    Mac OS X:Xcode常用快捷键
    分形图形神器XaoS
    [转]How to change Atheros AR9285 MAC addr on Win7(Win7下更改Atheros AR9285 MAC地址)
    利用pscp建立“右键发送到”菜单
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/2995233.html
Copyright © 2020-2023  润新知