10.18

一、build

    这道题就是字符串的一些判重操作。给你n个字符串,每个字符串通过“/”分成若干个文件,不同层数文件名相同也认为是不同文件,相同层数不同文件名认为是不同文件,然后让你求到达每一层以后,你需要建多少个文件。n<=2000,字符串长度最大100.

(1)纯模拟。

    我们发现,如果你现在枚举到第i个字符串的某一个文件,如果这个文件不需要建的话,那么它从开头到目前这个位置一定是可以与之前的字符串匹配上的。为了方面比较,我们把所有字符串的第一个/忽略,然后在每一个字符串的最后添加一个/,这样的话,我们每次只需要先统计一下这个字符串出现/的次数,然后尝试匹配之前的字符串,在匹配的同时记录一下最大能匹配的/的数量,两者相减就是你至少需要新建的文件数量。复杂度N^2*100,思路简单答案计算方便,所以可以卡过。这个思路也是我在考场上现想出来的,确实思路是对的,但是因为一些细节没有处理好,挂了60分。那么你发现,比赛的时候就算是简单的模拟题,你也要确保你的思路完全正确性以及考虑全面,不然就白整。有的时候觉得处理起来好麻烦,可以尝试换一个思路,会轻松不少。今天我最开始写的是通过文件名前的/来判断文件的个数,所有就比之前的复杂,然后自己也没有考虑完所有的情况,所以就没A掉。

#include<bits/stdc++.h>
using namespace std;
char s[2100][210];int n,m,ans;
int main(){
	freopen("build.in","r",stdin);
	freopen("build.out","w",stdout);
	scanf("%d",&n);
	scanf("%s",s[1]+1);
	m=strlen(s[1]+1);
	s[1][m+1]='/';m++;
	for(int i=2;i<=m;i++) if(s[1][i]=='/') ans++;
	printf("%d\n",ans);
	for(int i=2;i<=n;i++){
		scanf("%s",s[i]+1);
		m=strlen(s[i]+1);int x=0,y=0;
		s[i][m+1]='/';m++;
		for(int j=2;j<=m;j++) if(s[i][j]=='/') x++;
		for(int k=1;k<i;k++){
			int temp=0;
			for(int j=2;j<=m;j++){
				if(s[i][j]!=s[k][j]){
					y=max(y,temp);break;
				}
				if(s[k][j]=='/') temp++;
			}
			y=max(y,temp);
		}
		ans+=x-y;
		printf("%d\n",ans);
	}
	return 0;
}

(2)map的应用

    我们可以使用一个map数组,我们发现枚举每一个字符串的时候,我们已经知道了这个文件的层数和文件名,如果我们可以快速查出符合这个条件的文件在之前出现过没有,那我们就可以很快的求出答案。对于每一个字符串,我们从头开始扫,以/ /为分界线,把中间的文件名用string存储起来,然后搜索一下这个出现过没,如果没有,就直接计算答案,然后把剩下的存入。如果出现,就继续。复杂度N^2logN。

(3)trie树

        这道题就是快速搜索字符串,显然使用trie树是最快的,复杂度N*100。每次插入字符串,在插入的同时,根据trie树的结构我们可以判断当前是否是新插入的点,仍然按照之前的那种思路,最后一个位置加上一个/,然后我们通过判断新插入的点的/的数量来加答案。

#include<bits/stdc++.h>
using namespace std;
int ch[100010][60],n,ans,tot=1;
char s[2100];
void insert(char* s){
	int len=strlen(s+1);s[len+1]='/';int p=1;
	for(int k=2;k<=len+1;k++){
		int cc=0;
		if(s[k]>='0'&&s[k]<='9'){
			cc=s[k]-'0'+1+26;
		}else if(s[k]=='/') cc=0;
		else cc=s[k]-'a'+1;
		if(ch[p][cc]==0){
			ch[p][cc]=++tot;
			if(cc==0) ans++;
		}
		p=ch[p][cc];
	}
}
int main(){
	freopen("build.in","r",stdin);
	freopen("build.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%s",s+1);
		insert(s);
		printf("%d\n",ans);
	}
	return 0;
}

二、orzzzq

    给你n个扇形,让你给这n个扇形分别染上颜色,每相邻两个扇形的颜色不能一样,然后你一共有m种颜料,问你方案数。当时看到这道题的时候,不知道为什么没有思路,当时首先大脑给直觉好像是组合数,但m种颜料,要求相邻颜色不同,没有见过这种模型,感觉很不可做就直接跳过去写第三题了。现在想想,好像傻了点。一般这种题,好不好写就看你设计的状态如何。其实之前做过一道类似的题,还是自己太菜了,没有联想到。我们考虑,其实我们可以先确定一个点染得颜色,不过具体哪个颜色我们不管,就知道它是一个确定的颜色,然后如果我们通过这个算出了给n个扇形都染上色的方案数,那我们只需要把它乘m就求出了答案。那么我们设f[i][0]表示第i个扇形染得与第一个扇形染色不同的方案数,f[i][1]表示第i个扇形染与第一个颜色相同的方案数。然后我们很容易发现,f[i][1]=f[i-1][0],f[i][0]=f[i-1][0]*(m-2)+f[i-1][1]*(m-1),我们发现递推式中当前状态由上一个状态转移过来,而且系数是固定不变的。很容易想到我们需要使用矩阵乘法来优化递推,设计一个1*2的矩阵存储状态,一个2*2的状态转移矩阵,然后递推到f[n]就是把状态矩阵乘上状态转移矩阵的(n-1)次方。使用快速幂加速乘法就好了。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=1e9+7;
ll t,n,m,f[2],a[2][2];
void mul(ll f[2],ll a[2][2]){
	ll c[2];
	memset(c,0,sizeof(c));
	for(int i=0;i<2;i++)
		for(int k=0;k<2;k++)
			c[i]=(c[i]+f[k]*a[k][i]%mod)%mod;
	memcpy(f,c,sizeof(c));
}
void mulself(ll a[2][2]){
	ll c[2][2];
	memset(c,0,sizeof(c));
	for(int i=0;i<2;i++)
		for(int j=0;j<2;j++)
			for(int k=0;k<2;k++)
				c[i][j]=(c[i][j]+a[i][k]*a[k][j]%mod)%mod;
	memcpy(a,c,sizeof(c));
}
int main(){
	freopen("orzzzq.in","r",stdin);
	freopen("orzzzq.out","w",stdout);
	scanf("%lld",&t);
	while(t--){
		scanf("%lld%lld",&n,&m);
		if(n==1){
			printf("%lld\n",m);
			continue;
		}
		f[0]=0;f[1]=1;
		a[0][0]=m-2;a[0][1]=1;
		a[1][0]=m-1;a[1][1]=0;
		n--;
		for(;n;n>>=1){
			if(n&1) mul(f,a);
			mulself(a);
		}
		printf("%lld\n",m*f[0]%mod);
	}
	return 0;
}

 

Ubuntu 18.04 系统默认提供的 Python 版本通常为 Python 3.6 或更低版本,同时官方软件仓库中通常不会直接提供 Python 10.18 这样的版本。Python 10.18 并非官方发布的版本,可能是用户误写或混淆了版本号。目前 Python 官方发布的最新稳定版本为 Python 3.11 或 3.12 系列[^1]。 如果目标是安装特定版本的 Python(如 Python 3.11),可以通过以下方式实现: ### 1. 使用 `deadsnakes` PPA 安装特定 Python 版本 Ubuntu 用户可以通过 `deadsnakes` PPA 安装多个 Python 版本。例如安装 Python 3.11: ```bash sudo add-apt-repository ppa:deadsnakes/ppa sudo apt update sudo apt install python3.11 ``` 安装完成后,可以通过以下命令验证: ```bash python3.11 --version ``` ### 2. 设置默认 Python 版本 Ubuntu 18.04 默认的 `python` 命令指向 Python 2.x,而 `python3` 命令则指向系统默认的 Python 3.x 版本。若希望更改默认版本,可以使用 `update-alternatives` 命令进行配置: ```bash sudo update-alternatives --install /usr/bin/python python /usr/bin/python2 1 sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.6 2 sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.11 3 sudo update-alternatives --config python ``` 上述命令将允许用户在多个 Python 版本之间切换[^3]。 ### 3. 使用 `pyenv` 管理多个 Python 版本 如果需要在同一台机器上管理多个 Python 版本,推荐使用 `pyenv`。它允许用户在不修改系统环境的前提下灵活切换 Python 版本。安装 `pyenv` 的步骤如下: ```bash # 安装 pyenv git clone https://github.com/pyenv/pyenv.git ~/.pyenv # 配置环境变量 echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc echo 'eval "$(pyenv init --path)"' >> ~/.bashrc echo 'eval "$(pyenv init -)"' >> ~/.bashrc # 应用更改 source ~/.bashrc # 安装依赖 sudo apt update; sudo apt install --no-install-recommends make build-essential libssl-dev zlib1g-dev \ libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \ libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev ``` 安装完成后,可以通过以下命令安装和切换版本: ```bash pyenv install 3.11.0 pyenv global 3.11.0 python --version ``` ### 4. 注意事项 - **Python 版本兼容性**:某些软件包可能尚未支持 Python 3.11 或更高版本,因此在升级前应确认目标环境中的依赖是否兼容[^2]。 - **系统稳定性**:Ubuntu 18.04 的系统工具依赖于 Python 3.6,随意更改系统默认 Python 版本可能导致系统工具异常,建议使用虚拟环境或 `pyenv` 管理版本。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值