1. 程式人生 > 實用技巧 >第 45 屆國際大學生程式設計競賽(ICPC)亞洲區域賽(上海)M . Gitignore(模擬)

第 45 屆國際大學生程式設計競賽(ICPC)亞洲區域賽(上海)M . Gitignore(模擬)

連結:https://ac.nowcoder.com/acm/contest/9925/M
來源:牛客網

題目描述

Your git project (you don't need to be familiar with git to solve this problem) has some files that should be ignored from synchronizing. You need to calculate the minimum number of lines needed for gitignore.

Formally, your project is a folder. A folder can have files and sub folders. There are no empty folders (i.e. folders without any files or sub folders inside). Initially, the git software will synchronize all the files in your project. However, you can specify some files and folders in the settings (which is called gitignore) to exclude them from synchronizing. For each line in gitignore, you can specify either a file or all the files in a folder. You can not

ignore the whole project folder (i.e. an empty line in gitignore).

You are given paths for all the files in the project and whether they should be ignored or shouldn't. Your task is to calculate the minimum number of lines for gitignore.

輸入描述:

The input contains several test cases. The first line contains a single positive integer TT which is the number of test cases. For each test case, you are first given two non-negative numbers nn and mm. And then nn non-empty lines of file paths that should be ignored, and mm non-empty lines of file paths that should not be ignored.

The paths are strings containing lower-cased English alphabets and slashes ('/') only. Slashes are used to separate folders, sub folders and file name. For exapmle, "a/b/c/d" indicates folder "a" in the project folder, folder "b" in folder "a", folder "c" in "b" and file "d" in folder "c". All the paths are valid, specifically:

1. The path is non-empty and it always indicates a file (i.e. the path does not end with a slash).
2. The path does not start with a slash.
3. Folder names and file names are non-empty (i.e. there are no consecutive slashes).
4. File paths are always unique (i.e. all the paths in a test case are different).
5. In a folder, no sub folders and files share the same names. For example, there won't be two files "a/b/a" and "a/b/a/d" in one test case. However, files "a/b/a" and a/b/b"are allowed.

1≤n+m≤1001≤n+m≤100 holds and in the whole input there are no more than 1,0001,000 characters in file paths (i.e. the sum of lengths of file path strings in the whole input file is no more than 1,0001,000).

輸出描述:

TT lines of non-negative integers, the minimum number of gitignore lines for each test case.

示例1

輸入

複製

2
3 0
data/train
data/test
model
3 1
data/train
data/test
model
data/sample

輸出

複製

2
3

說明

In the first sample test case, the corresponding gitignore file contains 2 lines: a folder line "data/" and a file name "model".

In the second sample test case, the corresponding gitignore file contains 3 file lines: "data/train", "data/test" and "model".

模擬。首先不能ignore的檔案的路徑上的所有資料夾都是不能ignore的,然後從能ignore的資料夾裡找最少的能覆蓋所有需要ignore的檔案的資料夾。

一開始仿照檔案樹的思路,先是想到了字典樹但感覺寫起來很麻煩,然後嘗試把每個資料夾/檔案字串用map對映成節點,然後建樹跑類似樹dp的過程,但t了...只能過40%左右的點(看別人程式碼貌似也有這麼寫的就能過,暈了)。

最後還是學大佬寫法用set一通瞎搞...

#include <iostream>
#include <set>
#include <vector>
#include <cstring>
using namespace std;
int n, m;
int main()
{
	freopen("data.txt", "r", stdin);
	int t;
	cin >> t;
	while(t--)
	{
		int ans = 0;
		cin >> n >> m;
		vector<string> v;
		set<string> s1, s2;
		for(int i = 1; i <= n; i++)
		{
			string tmp;
			cin >> tmp;
			v.push_back(tmp);
		}
		for(int i = 1; i <= m; i++)
		{
			string tmp;
			cin >> tmp;
			for(int j = 1; j < tmp.size(); j++)
			{
				if(tmp[j] == '/')
				{
					s1.insert(tmp.substr(0, j));//每一個子資料夾都要標記
				}
			}
		}
		for(int i = 0; i < v.size(); i++)
		{
			bool pd = 1;
			for(int j = 0; j < v[i].size(); j++)
			{
				if(v[i][j] == '/')
				{
					string tmp = v[i].substr(0, j);
					if(s1.find(tmp) != s1.end()) continue;//不能直接ignore當前資料夾
					else if(s2.find(tmp) != s2.end())//當前資料夾在已經ignore的資料夾set裡出現過了,直接忽略
					{
						pd = 0;
						break;
					}
					else//插入
					{
						pd = 0;
						ans++;
						s2.insert(tmp);
						break;
					}
				}
			}
			if (pd && !s2.count(v[i]) && !s1.count(v[i])) ans++;//單個檔案
		}
		cout << ans << endl;
		
	}
	return 0;
}