uva 502(模拟)

题意:一些文件名,包扩名字和扩展符,-是想要删除,+是想要保存,是否能找出一个字符串,做到此类型的都删除,不符合此类型的保存,找不出这样的字符串输出IMPOSSIBLE,这个字符串是有这个字母但不确定用‘?’代替,文件名末尾和扩展符末尾可以用‘*’代替一个长序列,当然‘*’也可以代表为空。

题解:模拟做就可以了,先分情况,不然思路会很乱(表示自己开始思路很乱的写了好久一直wa),先把给出的所有字符串分成4份,需要删除的和保留的,‘.’前面和后面的,然后找到需要删除的字符串'.'左右最短长度两个,如果在删除字符串中有比这个长度更长的,需要加'*',所以有4种情况,'.'前是否加'*','.'后是否加'*',然后和需要保留的字符串一一匹配,有星号要和长度大于等于自己的判断,没有星号直接判断长度和自己相等的就可以了,思路清晰就很好做了。

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
using namespace std;
const int N = 1000 + 5;

string str[N];
string del1[N];
string del2[N];
string save1[N];
string save2[N];
char ans1[N];
char ans2[N];
int n, num1, num2, mind1, mind2, flag1, flag2, no1, no2;

void init() {
	n = num1 = num2 = flag1 = flag2 = no1 = no2 = 0;
	mind1 = mind2 = N;
	for (int i = 0; i < N; i++)
		save1[i] = save2[i] = del1[i] = del2[i] = "";
	memset(ans2, 0, sizeof(ans2));
	memset(ans1, 0, sizeof(ans1));
}

int main() {
	int t, i, j;
	scanf("%d", &t);
	getchar();
	getchar();
	while (t--) {
		init();
		while (getline(cin, str[n])) {
			if (str[n] != "")
				n++;
			else
				break;
		}
		for (i = 0; i < n; i++) {
			int len = str[i].size(), j;
			if (str[i][0] == '+') {
				for (j = 1; j < len; j++)
					if (str[i][j] != '.')
						save1[num1] += str[i][j];
					else
						break;
				if (j != len)
					for (j = j + 1; j < len; j++)
						save2[num1] += str[i][j];
				num1++;
			}
			else {
				for (j = 1; j < len; j++)
					if (str[i][j] != '.')
						del1[num2] += str[i][j];
					else
						break;
				if (mind1 > j - 1)
					mind1 = j - 1;
				if (mind2 > len - j - 1)
					mind2 = len - j - 1;
				if (j != len)
					for (j = j + 1; j < len; j++)
						del2[num2] += str[i][j];
				num2++;
			}
		}
		for (i = 0; i < mind1; i++) {
			int temp = 0;
			for (j = 0; j < num2 - 1; j++) {
				if (del1[j][i] == del1[j + 1][i])
					temp++;
			}
			if (temp == num2 - 1)
				ans1[i] = del1[j][i];
			else
				ans1[i] = '?';
		}
		for (i = 0; i < mind2; i++) {
			int temp = 0;
			for (j = 0; j < num2 - 1; j++)
				if (del2[j][i] == del2[j + 1][i])
					temp++;
			if (temp == num2 - 1)
				ans2[i] = del2[j][i];
			else
				ans2[i] = '?';
		}
		for (j = 0; j < num2; j++) {
			int len = del1[j].size();
			if (len > mind1) {
				flag1 = 1;
				break;
			}
		}//文件名尾部是否有星号
		for (j = 0; j < num2; j++) {
			int len = del2[j].size();
			if (len > mind2) {
				flag2 = 1;
				break;
			}
		}//扩展符尾部是否有星号
		if (flag1) {
			int i, j;
			for (i = 0; i < num1; i++) {
				int len = save1[i].size();
				if (len < mind1)//pass
					continue;
				int temp = 0;
				for (j = 0; j < mind1; j++) {
					if (save1[i][j] == ans1[j] || ans1[j] == '?')
						temp++;
				}
				if (temp == mind1) {
					no1 = 1;
					break;
				}
			}
		}
		if (flag2) {
			int i, j;
			for (i = 0; i < num1; i++) {
				int len = save2[i].size();
				if (len < mind2)//pass
					continue;
				int temp = 0;
				for (j = 0; j < mind2; j++)
					if (save2[i][j] == ans2[j] || ans2[j] == '?')
						temp++;
				if (temp == mind2) {
					no2 = 1;
					break;
				}
			}
		}
		if (!flag1) {
			int i, j;
			for (i = 0; i < num1; i++) {
				int len = save1[i].size();
				if (len != mind1)//pass
					continue;
				int temp = 0;
				for (j = 0; j < mind1; j++)
					if (save1[i][j] == ans1[j] || ans1[j] == '?')
						temp++;
				if (temp == mind1) {
					no1 = 1;
					break;
				}
			}
		}
		if (!flag2) {
			int i, j;
			for (i = 0; i < num1; i++) {
				int len = save2[i].size();
				if (len != mind2)//pass
					continue;
				int temp = 0;
				for (j = 0; j < mind2; j++)
					if (save2[i][j] == ans2[j] || ans2[j] == '?')
						temp++;
				if (temp == mind2) {
					no2 = 1;
					break;
				}
			}
		}
		if (no1 && no2)
			printf("IMPOSSIBLE\n");
		else {
			printf("DEL ");
			int i, j;
			for (i = 0; i < mind1; i++)
				printf("%c", ans1[i]);
			if (flag1)
				printf("*");
			printf(".");
			for (i = 0; i < mind2; i++)
				printf("%c", ans2[i]);
			if (flag2)
				printf("*");
			printf("\n");
		}
		if (t)
			cout << endl;
	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值