[Codeforces 66C] Petya and File System //字符串暴力+map/建树dfs

Problem

题目链接

题意:给不定行字符串代表文件目录,diskName:\folder1\folder2…\ foldern\fileName.xxx,(n>=1),每行字符串建立一个文件,保证没有相同的行。磁盘不算文件夹,求文件夹中直接或简介包含的子文件夹的最大数量ans1,和文件夹中直接或间接包含的最大文件数ans2。

Solutions

1.暴力+map

暴力思路:ans2直接O(n2)暴力枚举找[磁盘名+根文件夹名]相同的行即可。ans1,用map维护每个相同[磁盘名+根文件夹名]下的直接或间接包含的子文件夹数,O(n2)暴力枚举,求当前串对map[磁盘名+根文件夹名]的贡献(找当前串在前面的串中未出现过的文件夹数量),更新ans1最大值。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<map>
#include<algorithm>
#include<queue>
#include<math.h>
#include<set>
#include<vector>
using namespace std;
#define Inf 0x7fffffff
typedef long long ll;
const int N=107;
string s[N][N],ss[N];
int cnt=0,k[N],ans1,ans2;
map<string,int>mp;
int main(){
	while(cin>>ss[++cnt]);--cnt;
	for(int i=1;i<=cnt;i++){
		s[i][0]+=ss[i][0];
		int l=2,len=ss[i].length();
		while(l<len){
			if(ss[i][l]=='\\')k[i]++;
			else s[i][k[i]]+=ss[i][l];
			l++;
		}
	}
	for(int i=1;i<=cnt;i++){
		int now=1;
		for(int j=i+1;j<=cnt;j++)
			if(s[i][0]==s[j][0]&&s[i][1]==s[j][1])now++;
		ans2=max(ans2,now);
	}
	for(int i=1;i<=cnt;i++){
		if(!mp.count(s[i][0]+s[i][1])){//没出现过,直接新建
			mp[s[i][0]+s[i][1]]+=k[i]-2;
			ans1=max(ans1,mp[s[i][0]+s[i][1]]);
			continue;
		}
		int now=0;
		for(int j=1;j<i;j++){//出现过,枚举前面的串,求出i中没出现过的子文件夹数量,即对map[s[i][0]+s[i][1]]的贡献
			if(s[i][0]!=s[j][0]||s[i][1]!=s[j][1])continue;
			int n=0;
			for(int o=2;o<k[i]&&o<k[j];o++)if(s[i][o]==s[j][o])n++;else break;
			now=max(now,n);
		}
		if(k[i]-2-now>0)mp[s[i][0]+s[i][1]]+=k[i]-2-now;
		ans1=max(ans1,mp[s[i][0]+s[i][1]]);
	}
	cout<<ans1<<" "<<ans2;
}

WA log:
· while(cin>>ss[++cnt]);输入,最后是会加了一次cnt,要减去。
· 找ans2时,第二层 for( j )循环的循环终止位置不能是cnt,而应该只枚举已经出现过的串,例如下面数据
D:\A\B\C\D.txt
D:\E\F\H\I.txt
D:\E\F\J.txt
i枚举Line2时j不能枚举到Line3,否则F文件夹也相同会跳过不计,i枚举2和3时都不会计入这个F文件夹

2.建树dfs

思路:以磁盘和文件夹名dfs建字符串树,磁盘深度为1,ans2为叶子节点的数量,ans1为深度为2的节点的子孙数的最大值。

猜你喜欢

转载自blog.csdn.net/qq_45530271/article/details/104422257