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的节点的子孙数的最大值。