M - Gitignore

该问题要求计算在git项目中,为了忽略某些文件和文件夹,gitignore文件最少需要多少行。题目提供了输入格式和样例,包括需要忽略和不需要忽略的文件路径,以及测试用例的数量。输出是每个测试用例对应的gitignore最少所需的行数。

https://codeforces.com/gym/102900/problem/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.

Input
The input contains several test cases. The first line contains a single positive integer T which is the number of test cases. For each test case, you are first given two non-negative numbers n and m. And then n non-empty lines of file paths that should be ignored, and m 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:

The path is non-empty and it always indicates a file (i.e. the path does not end with a slash).
The path does not start with a slash.
Folder names and file names are non-empty (i.e. there are no consecutive slashes).
File paths are always unique (i.e. all the paths in a test case are different).
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≤100 holds and in the whole input there are no more than 1,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,000).

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

Example
Input
2
3 0
data/train
data/test
model
3 1
data/train
data/test
model
data/sample
Output
2
3
Note
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”.
代码:

#include<bits/stdc++.h>
#define ls l,mid,rt<<1
#define rs mid+1,r,rt<<1|1
#define endl '\n'
#define ps puts("###")
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn = 1e6+10;
const double eps = 1e-12;
const ll mod = 1e9+7;
ll t,m,n,k,s;
string x,y;
map<string,ll>q,vis;
string a[1001];
int main()
{
    cin>>t;
    while(t--)
    {
        cin>>n>>m;
        vis.clear();
        q.clear();
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
        }
        for(int i=1;i<=m;i++)
        {
            cin>>x;
            y="";
            for(int j=0;j<x.size();j++)
            {
                y+=x[j];
                if(x[j]=='/')
                {
                    vis[y]=1;
                }
            }
        }
        s=0;
        for(int i=1;i<=n;i++)
        {
            y="";
            int flag=0;
            for(int j=0;j<a[i].size();j++)
            {
                y+=a[i][j];
                if(a[i][j]=='/')
                {
                    if(q[y])
                    {
                        flag=1;
                        break;
                    }

                    if(!vis[y])
                    {
                        q[y]=1;
                        s++;
                        flag=1;
                        break;
                    }

                }
            }
            if(flag==0)
            {
                s++;
            }
        }
        cout<<s<<endl;
    }
}

(venv) gapinyc@DESKTOP-9QS7RL5:~/superset$ flask shell ?charset=utf8mb4ASE_URI: mysql+pymysql://superset_user Loaded your LOCAL configuration at [/home/gapinyc/superset/superset_config.py] 2025-10-25 07:16:58,944:DEBUG:superset.utils.logging_configurator:logging was configured successfully 2025-10-25 07:16:58,949:DEBUG:root:Configured event logger of type <class 'superset.utils.log.DBEventLogger'> 2025-10-25 07:16:58,952:INFO:superset.initialization:Setting database isolation level to READ COMMITTED 2025-10-25 07:16:58,953:ERROR:flask_appbuilder.security.sqla.manager:DB Creation and initialization failed: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on '192.168.110.204\\r' ([Errno -2] Name or service not known)") (Background on this error at: https://sqlalche.me/e/14/e3q8) (venv) gapinyc@DESKTOP-9QS7RL5:~/superset$ cat -A /home/gapinyc/superset/.env # M-fM-^UM-0M-fM-^MM-.M-eM-:M-^SM-hM-?M-^^M-fM-^NM-%$ DB_HOST=192.168.110.204$ DB_PORT=3306$ DB_USER=superset$ DB_PASSWORD=password$ DB_NAME=superset$ $ # Superset M-iM-^EM-^MM-gM-=M-.$ SECRET_KEY=kNeeshADyj2cmejJjWqJf590qM2Hkf6LrspLE8dgzatDmogrn4a8SAma(venv) gapinyc@DESKTOP-9QS7RL5:~/superset$ cat -A /home/gapinyc/superset/superset_config.pycat -A /home/gapinyc/superset/superset_config.py | grep -A5 -B5 '\^M' import os^M$ ^M$ # -------------------------------^M$ # M-fM-^UM-0M-fM-^MM-.M-eM-:M-^SM-iM-^EM-^MM-gM-=M-.M-oM-<M-^ZM-dM-=M-?M-gM-^TM-( MySQL^M$ # -------------------------------^M$ SQLALCHEMY_DATABASE_URI = (^M$ f"mysql+pymysql://{os.getenv('MYSQL_USER')}:{os.getenv('MYSQL_PASSWORD')}"^M$ f"@{os.getenv('MYSQL_HOST')}/{os.getenv('DATABASE')}?charset=utf8mb4"^M$ )^M$ ^M$ print("SQLALCHEMY_DATABASE_URI:", SQLALCHEMY_DATABASE_URI)^M$ ^M$ # -------------------------------^M$ # Superset M-eM-^EM-^CM-fM-^UM-0M-fM-^MM-.M-fM-^UM-0M-fM-^MM-.M-eM-:M-^S URIM-oM-<M-^HM-eM-^MM-3M-hM-^GM-*M-hM-:M-+M-eM-^EM-^CM-fM-^UM-0M-fM-^MM-.M-eM--M-^XM-eM-^BM-(M-dM-=M-^MM-gM-=M-.M-oM-<M-^I^M$ # -------------------------------^M$ SQLALCHEMY_TRACK_MODIFICATIONS = False^M$ ^M$ # -------------------------------^M$ # Flask App Builder M-iM-^EM-^MM-gM-=M-.^M$ # -------------------------------^M$ SECRET_KEY = os.getenv('SUPERSET_SECRET_KEY', 'your-super-secret-key-change-in-prod')^M$ ^M$ # -------------------------------^M$ # M-iM-^BM-.M-dM-;M-6M-iM-^EM-^MM-gM-=M-.M-oM-<M-^HM-eM-^OM-/M-iM-^@M-^IM-oM-<M-^I^M$ # -------------------------------^M$ # M-eM-&M-^BM-fM-^^M-^\M-iM-^\M-^@M-hM-&M-^AM-eM-^OM-^QM-iM-^BM-.M-dM-;M-6M-eM-^QM-^JM-hM--M-&M-gM--M-^IM-eM-^JM-^_M-hM-^CM-=M-oM-<M-^LM-hM-/M-7M-iM-^EM-^MM-gM-=M-.^M$ # MAIL_SERVER = 'localhost'^M$ # MAIL_USE_TLS = False^M$ # MAIL_USERNAME = 'no-reply@example.com'^M$ # MAIL_PASSWORD = ''^M$ # MAIL_DEFAULT_SENDER = 'no-reply@example.com'^M$ ^M$ # -------------------------------^M$ # M-iM-^]M-^YM-fM-^@M-^AM-hM-5M-^DM-fM-:M-^PM-eM-^RM-^LM-gM-<M-^SM-eM--M-^XM-oM-<M-^HM-eM-^OM-/M-iM-^@M-^IM-dM-<M-^XM-eM-^LM-^VM-oM-<M-^I^M$ # -------------------------------^M$ # DATA_CACHE_CONFIG = {^M$ # 'CACHE_TYPE': 'simple'^M$ # } (venv) gapinyc@DESKTOP-9QS7RL5:~/superset$ sed -i 's/\r$//' /home/gapinyc/superset/superset_config.py (venv) gapinyc@DESKTOP-9QS7RL5:~/superset$ cat -A /home/gapinyc/superset/superset_config.py | grep -A5 -B5 '\^M' import os$ $ # -------------------------------$ # M-fM-^UM-0M-fM-^MM-.M-eM-:M-^SM-iM-^EM-^MM-gM-=M-.M-oM-<M-^ZM-dM-=M-?M-gM-^TM-( MySQL$ # -------------------------------$ SQLALCHEMY_DATABASE_URI = ($ f"mysql+pymysql://{os.getenv('MYSQL_USER')}:{os.getenv('MYSQL_PASSWORD')}"$ f"@{os.getenv('MYSQL_HOST')}/{os.getenv('DATABASE')}?charset=utf8mb4"$ )$ $ print("SQLALCHEMY_DATABASE_URI:", SQLALCHEMY_DATABASE_URI)$ $ # -------------------------------$ # Superset M-eM-^EM-^CM-fM-^UM-0M-fM-^MM-.M-fM-^UM-0M-fM-^MM-.M-eM-:M-^S URIM-oM-<M-^HM-eM-^MM-3M-hM-^GM-*M-hM-:M-+M-eM-^EM-^CM-fM-^UM-0M-fM-^MM-.M-eM--M-^XM-eM-^BM-(M-dM-=M-^MM-gM-=M-.M-oM-<M-^I$ # -------------------------------$ SQLALCHEMY_TRACK_MODIFICATIONS = False$ $ # -------------------------------$ # Flask App Builder M-iM-^EM-^MM-gM-=M-.$ # -------------------------------$ SECRET_KEY = os.getenv('SUPERSET_SECRET_KEY', 'your-super-secret-key-change-in-prod')$ $ # -------------------------------$ # M-iM-^BM-.M-dM-;M-6M-iM-^EM-^MM-gM-=M-.M-oM-<M-^HM-eM-^OM-/M-iM-^@M-^IM-oM-<M-^I$ # -------------------------------$ # M-eM-&M-^BM-fM-^^M-^\M-iM-^\M-^@M-hM-&M-^AM-eM-^OM-^QM-iM-^BM-.M-dM-;M-6M-eM-^QM-^JM-hM--M-&M-gM--M-^IM-eM-^JM-^_M-hM-^CM-=M-oM-<M-^LM-hM-/M-7M-iM-^EM-^MM-gM-=M-.$ # MAIL_SERVER = 'localhost'$ # MAIL_USE_TLS = False$ # MAIL_USERNAME = 'no-reply@example.com'$ # MAIL_PASSWORD = ''$ # MAIL_DEFAULT_SENDER = 'no-reply@example.com'$ (venv) gapinyc@DESKTOP-9QS7RL5:~/superset$ flask shell ?charset=utf8mb4ASE_URI: mysql+pymysql://superset_user Loaded your LOCAL configuration at [/home/gapinyc/superset/superset_config.py] 2025-10-25 07:18:41,114:DEBUG:superset.utils.logging_configurator:logging was configured successfully 2025-10-25 07:18:41,120:DEBUG:root:Configured event logger of type <class 'superset.utils.log.DBEventLogger'> 2025-10-25 07:18:41,122:INFO:superset.initialization:Setting database isolation level to READ COMMITTED 2025-10-25 07:18:41,123:ERROR:flask_appbuilder.security.sqla.manager:DB Creation and initialization failed: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on '192.168.110.204\\r' ([Errno -2] Name or service not known)") (Background on this error at: https://sqlalche.me/e/14/e3q8) (venv) gapinyc@DESKTOP-9QS7RL5:~/superset$
最新发布
10-26
你仍然遇到错误: ``` Can't connect to MySQL server on '192.168.110.204\\r' ``` 但最关键的是,从你的 `cat -A` 输出来看,**`.env` 文件已经被严重损坏或编码错误**! --- ## 🔥 问题定位:`.env` 文件是乱码 看这一行: ```bash # M-fM-^UM-0M-fM-^MM-.M-eM-:M-^SM-hM-?M-^^M-fM-^NM-%$ ``` 这是典型的 **UTF-8 字节序列被错误解释为 Latin-1 或其他单字节编码的结果**。 说明:你用一个不支持中文/特殊字符的编辑器打开了文件,或者复制粘贴时引入了编码污染。 更糟糕的是: ```bash SECRET_KEY=kNeeshADyj2cmejJjWqJf590qM2Hkf6LrspLE8dgzatDmogrn4a8SAma(venv) ``` → `SECRET_KEY` 值末尾直接拼上了 `(venv)`,说明你在终端里复制粘贴时不小心把命令提示符也粘进去了! --- ## ✅ 终极解决方案:重建 `.env` 文件 ### ✅ 步骤 1:删除并重建 `.env` ```bash rm /home/gapinyc/superset/.env nano /home/gapinyc/superset/.env ``` 输入以下内容(请根据实际情况修改): ```env # Database Settings MYSQL_USER=superset_user MYSQL_PASSWORD=your_real_password MYSQL_HOST=192.168.110.204:3306 DATABASE=superset # Superset Settings SUPERSET_SECRET_KEY=your-super-secret-key-change-in-prod ``` 📌 注意事项: - 不要加引号; - 使用纯英文注释(避免中文导致编码问题); - 每个值都不能有空格或换行残留; - `MYSQL_HOST` 包含端口没问题; - `SUPERSET_SECRET_KEY` 要足够长且随机(用于加密 session); 保存退出:`Ctrl+O` → 回车 → `Ctrl+X` --- ### ✅ 步骤 2:确保 `superset_config.py` 正确加载环境变量 确保文件开头有显式加载 `.env` 的代码: ```python import os from dotenv import load_dotenv # 显式加载 .env basedir = os.path.abspath(os.path.dirname(__file__)) load_dotenv(os.path.join(basedir, '.env')) # 构建数据库 URI SQLALCHEMY_DATABASE_URI = ( f"mysql+pymysql://{os.getenv('MYSQL_USER')}:{os.getenv('MYSQL_PASSWORD')}" f"@{os.getenv('MYSQL_HOST')}/{os.getenv('DATABASE')}?charset=utf8mb4" ) print("SQLALCHEMY_DATABASE_URI:", repr(SQLALCHEMY_DATABASE_URI)) ``` > ⚠️ `repr()` 可以显示字符串中的隐藏字符如 `\r`, `\n` --- ### ✅ 步骤 3:验证 `.env` 是否正常加载 运行测试脚本: ```bash python -c " import os from dotenv import load_dotenv load_dotenv('.env') print('MYSQL_USER:', repr(os.getenv('MYSQL_USER'))) print('MYSQL_PASSWORD:', repr(os.getenv('MYSQL_PASSWORD'))) print('MYSQL_HOST:', repr(os.getenv('MYSQL_HOST'))) print('DATABASE:', repr(os.getenv('DATABASE'))) " ``` ✅ 正确输出应类似: ``` MYSQL_USER: 'superset_user' MYSQL_PASSWORD: 'your_real_password' MYSQL_HOST: '192.168.110.204:3306' DATABASE: 'superset' ``` ❌ 如果出现 `'192.168.110.204:3306\r'` 或乱码,则说明文件仍有问题。 --- ### ✅ 步骤 4:再次运行 `flask shell` ```bash flask shell ``` 观察输出中是否还有 `\\r` 或乱码。 你应该会看到类似: ``` SQLALCHEMY_DATABASE_URI: 'mysql+pymysql://superset_user:your_real_password@192.168.110.204:3306/superset?charset=utf8mb4' ``` 如果没有报错,并进入 Python shell,说明成功! --- ### ✅ 补充:防止未来出错的最佳实践 | 措施 | 方法 | |------|------| | **使用 LF 换行** | 在 VS Code 左下角确认是 `LF` 而非 `CRLF` | | **禁用富文本粘贴** | 不要从 Word、微信、网页直接复制内容到 `.env` | | **设置文件权限** | `chmod 600 .env` 防止泄露 | | **加入 .gitignore** | 确保 `.env` 不提交到 Git | | **使用 pre-commit 检查** | 自动检测 CRLF 和敏感词 | --- ### ✅ 最终检查清单 | 检查项 | 命令 | |--------|------| | 查看 .env 内容是否干净 | `cat -A .env` (不能有 `^M` 或乱码) | | 测试环境变量加载 | `python -c "import os; from dotenv import load_dotenv; load_dotenv(); print(repr(os.getenv('MYSQL_HOST')))"` | | 确认网络连通性 | `nc -zv 192.168.110.204 3306` | | 检查 MySQL 用户权限 | 登录 MySQL 执行 `SELECT User, Host FROM mysql.user WHERE User='superset_user';` | ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值