基础算法_模拟

题意:

题意啊555,好难懂啊
大概意思是这个亚子的,就是给了一些文件夹,文件夹里面有子文件夹和文件,有n个是可以忽略的,m个不可以忽略的,问最少可以忽略多少个文件??(什么意思呢?也就是一个文件夹里面的文件都是可以忽略的,就只保留文件夹就好了)

思路:

可以忽略掉的文件假设有这两个:
a/b/a
c/b/c
(1)如果按单词存储,第二个文件会被删掉,然而第二个文件不可以删

(2)如果是按照前缀存的话呢??

  1. 我们先存的是不能删的文件路径的所有前缀

  2. 如果能删的路径和不能删的路径有公用前缀,就继续往下面找子文件夹,并且把没有出现过的目录标记一下,如果这个第二次被标记的目录再次出现,那么ans - 1(因为不能忽略一整个文件夹)

如果每个文件夹都可以直接忽略的话,ans = n就是答案,就没有任何意义了。

代码实现:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 3e6 + 5;
string a[maxn];
string b[maxn];
map<string,int>mp;
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		int n,m;
		scanf("%d%d",&n,&m);
		mp.clear();
		for(int i = 1;i <= n;i++){
			cin >> a[i];
		}
		string tmp = "";
		for(int j = 1;j <= m;j++){
			//为什么不能存单词???
			/*
			可以忽略掉的文件假设有这两个:
			a/b/a
			c/b/c
			如果按单词存储,第二个文件会被删掉,然而第二个文件不可以删

			如果是按照前缀存的话呢??
			首先,我们先存的是不能删的文件路径的所有前缀
			然后,如果能删的路径和不能删的路径有公用前缀,
			就继续往下面找子文件夹,并且把没有出现过的目录标记一下,
			如果这个第二次被标记的目录再次出现,那么ans - 1
			(因为不能忽略一整个文件夹)
            
            //如果每个文件都可以忽略的话,ans = n就是答案,就没有任何意义了。
			*/
			cin >> b[j];
			int len = b[j].length();
			tmp = "";
			for(int k = 0;k < len;k++){
				tmp += b[j][k];
				if(b[j][k] == '/'){
					mp[tmp] = 1;
				}
			}
		}
		tmp = "";
		int ans = n;
		//查询时的跳转问题??
		for(int i = 1;i <= n;i++){
			int len = a[i].length();
			tmp = "";
			for(int k = 0;k < len;k++){
				tmp += a[i][k];
				if(a[i][k] == '/'){
					if(mp[tmp] == 1) continue;//公用前缀,接着查找
					else if(mp[tmp] == 2){//再次出现,删掉
						ans--;
						break;
						//而且已经合并了,肯定是不能再往下面找了啊!
					}
					else mp[tmp] = 2;//标记一下刚出现的文件目录
				}
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值