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; }