UVA 502 - DEL command(贪心构造)

 DEL command 

It is required to find out whether it is possible to delete given files from MS-DOS directory executing the DEL command of MS-DOS operation system only once. There are no nested subdirectories.

A note 

DEL command has the following format: DEL wildcard


The actual wildcard as well as a full file name can be made up either of a name containing 1 up to 8 characters or of a name and extension, containing up to 3 characters. The point character ``." separates the extension from the file name. The extension can be empty and this is equivalent to a name without any extension (in this case a wildcard ends with a point). In a wildcard the characters ``?" and ``*" can be used. A question mark substitutes exactly one character of the full file name excluding a point, an asterisk any sequence of characters (containing no points) even empty one. An asterisk can appear only at the last position of the name and the extension.


MS-DOS system can permit maybe other wildcards but they can not be used in this task. File names and extensions consist only of Latin capitals and digits.

Input 

The first line of the input is an integer M, then a blank line followed by M datasets. There is a blank line between datasets.

Input data for each dataset contains a list of full file names without empty lines and spaces. Each name is written in a separate line of input data file and preceded with a control sign: ``-" for delete or ``+" for keep. Full file names are not repeated. The list comprises at least one file, and at least one file is marked to be deleted. There are no more than 1000 files.

Output 

For each dataset, write to the first line of output the required DEL command (only one proposal) orIMPOSSIBLE if there is no solution. A space should separate ``DEL" from wildcard. Print a blank line between datasets.

Sample Input 

1

-BP.EXE
-BPC.EXE
+TURBO.EXE

Possible output 

DEL ?P*.*

题意:构造一条指令,删除-的文件,不删除+的文件,?代表任意字符,*代表任意个数字符,*只能加在末尾。

思路:贪心,把要删除和保留的分开保存,然后对于要删除的每一个字母,如果全相同,就用这个字母,如果有不同,就用?,如果长短不一,末尾就用*填,然后在用构造出来的串去和保留的一一判断,如果有一个保留会被删除,就是错的。

代码:

#include <stdio.h>
#include <string.h>

const int N = 1005;

int t, n[2], sn, sn1;
char str[15], str1[15];
struct F {
	char a[15], b[15];
} f[2][N];

void tra() {
	int s;
	if (str[0] == ‘-‘) s = 0;
	else s = 1;
	int i = 1, len = strlen(str), an = 0, bn = 0;
	for (; str[i] != ‘.‘ && i < len; i++)
		f[s][n[s]].a[an++] = str[i];
	for (i = i + 1; i < len; i++)
		f[s][n[s]].b[bn++] = str[i];
	n[s]++;
}

int judge(int i) {
	char c = f[0][0].a[i];
	for (int j = 0; j < n[0]; j++) {
		if (f[0][j].a[i] != c) {
			if (f[0][j].a[i] == ‘\0‘ || c == ‘\0‘) return -1;
			return 0;
		}
	}
	return 1;
}

int judge1(int i) {
	char c = f[0][0].b[i];
	for (int j = 0; j < n[0]; j++) {
		if (f[0][j].b[i] != c) {
			if (f[0][j].b[i] == ‘\0‘ || c == ‘\0‘) return -1;
			return 0;
		}
	}
	return 1;
}

bool ok1(int i) {
	int len = strlen(str);
	if (str[len - 1] == ‘*‘) len--;
	else if (len < strlen(f[1][i].a)) return false;
	for (int j = 0; j < len; j++) {
		if (str[j] != ‘\0‘ && f[1][i].a[j] == ‘\0‘) return false;
		if (str[j] != ‘?‘ && str[j] != f[1][i].a[j]) return false;
	}
	return true;
}

bool ok2(int i) {
	int len = strlen(str1);
	if (str1[len - 1] == ‘*‘) len--;
	else if (len < strlen(f[1][i].b)) return false;
	for (int j = 0; j < len; j++) {
		if (str1[j] != ‘\0‘ && f[1][i].b[j] == ‘\0‘) return false;
		if (str1[j] != ‘?‘ && str1[j] != f[1][i].b[j]) return false;
	}
	return true;
}

bool OK(int i) {
	if (ok1(i) && ok2(i)) return true;
	return false;
}

void make() {
	sn = 0; sn1 = 0; int i;
	memset(str, 0, sizeof(str));
	memset(str1, 0, sizeof(str1));
	for (i = 0; ; i++) {
		if (judge(i) == 1) {
			if (f[0][0].a[i] == ‘\0‘) break;
			str[sn++] = f[0][0].a[i];
		}
		else if (judge(i) == -1) {
			str[sn++] = ‘*‘;
			break;
		}
		else str[sn++] = ‘?‘;
	}
	for (i = 0; ; i++) {
		if (judge1(i) == 1) {
			if (f[0][0].b[i] == ‘\0‘) break;
			str1[sn1++] = f[0][0].b[i];
		}
		else if (judge1(i) == -1) {
			str1[sn1++] = ‘*‘;
			break;
		}
		else str1[sn1++] = ‘?‘;
	}
}

void init() {
	memset(n, 0, sizeof(n));
	memset(f, 0, sizeof(f));
	while (gets(str) != NULL && str[0] != ‘\0‘) {
		tra();
	}
}

void solve() {
	make();
	for (int i = 0; i < n[1]; i++) {
		if (OK(i)) {
			printf("IMPOSSIBLE\n");
			if (t) printf("\n");
			return;
		}
	}
	printf("DEL %s.%s\n", str, str1);
	if (t) printf("\n");
}

int main() {
	scanf("%d%*c%*c", &t);
	while (t--) {
		init();
		solve();
	}
	return 0;
}


UVA 502 - DEL command(贪心构造)

上一篇:AWS云平台的服务概览(上):基础服务


下一篇:taobao网店观察