10月16日 CSP-S

T1 小w的爱情密码

【问题描述】

小W终于鼓起勇气向小M表白,然而只是有勇气写情书。

为了防止情书内容被同学窃取,小W给情书加密。

小M的解密方式很简单,假设情书是字符串S1,小W给她的解密串是 S2,小M会重复地完成“在S1中找到子串S2并删除”这一操作直到在 S1 中找不到S2。

假如你是小M,请你确定情书的最终内容。

【输入格式】
第一行一个字符串 S1。

第二行一个字符串 S2。

【输出格式】
一行一个字符串 S,表示最终内容。

对于 30% 的数据,保证Length(S1) <= 1000。

对于 100% 的数据,保证Length(S1) <= 10^6,

Length(S2) <= 100。字符都是小写字母。

100pts:

这是一道标准的贪心。

其实它的难点在于你需要用一个数组存这个东西,还有证明贪心。

遍历S1,将这个字符加入一个数组a,然后每加入一次就判断最后面s2.size()个是否能消掉。

因为消掉一次之后就不会再出现新的情况了,所以这个方法是正确的。

code:

#include<bits/stdc++.h>
using namespace std;
string s,t;
vector<char> a;
int main(){
//	freopen("censor.in","r",stdin);
//	freopen("censor.out","w",stdout);
	cin>>s>>t;
	for(int i=0;i<s.size();i++){
		a.push_back(s[i]);
		int j=a.size()-1;
		if(j<t.size()-1) continue;
		for(int k=t.size()-1;k>=0;j--,k--){
			if(t[k]!=a[j]){
				break;
			}
			if(k==0){
				for(int k=1;k<=t.size();k++){
					a.pop_back();
				}
			}
		}	
	}
	for(int i=0;i<a.size();i++){
		cout<<a[i];
	}
} 

T2 飞船监控站

coding...

T3 旅游规划

【问题描述】
W市的交通规划出现了重大问题,市政府下决心在全市的各大交通路口安排交通疏导员来疏导密集的车流。但由于人员不足,W市市长决定只在最需要安排人员的路口安放人员。具体说来,W市的交通网络十分简单,它包括n个交叉路口和n-1条街道,任意一条街道连接两个交叉路口,并且任意两个交叉路口之间都存在一条路径互相连接。经过长期调查结果显示如果一个交叉路口位于W市交通网的最长路径上,那么这个路口必然拥挤不堪,所谓最长路径定义为某条路径p=(v1,v2,v3…vk),路径经过的路口各不相同且城市中不存在长度>k的路径(因此可能存在着不唯一的最长路径)。因此W市市长希望知道有哪些路口位于城市交通网的最长路径之上。

【输入格式】
第一行包括一个整数n。

之后的n-1行每行包括两个整数u, v表示编号为u和v的路口之间存在着一条街道(注意:路口被依次编号为0到n-1)

【输出格式】
输出包括若干行,每行包括一个整数——某个位于最长路上路口的编号。

为了确保解唯一,我们规定位于所有最长路上的路口按编号顺序从小到大输出。

【数据范围及约定】
对于50%的数据保证n<=1000

对于100%的数据保证n<=200000

50pts

暴力换根+dfs,轻松50。(虽然我赛时爆0了)

不过多赘述

100pts

把暴力换根优化一下,记录每一个点距离根节点的长度(用于计算),再记录每一个点的深度。

最后找最大的节点的最大的两条路径就结束了。

code:

#include <bits/stdc++.h>
using namespace std;

const int N = 200010, M = N << 1;
vector<int> a[N];
int len1[N], len2[N], tmp[N], tofa[N];
int n, maxd;

void dfs_len(int u, int fa) {
	for (int i = 0; i < a[u].size(); i++) {
		int j = a[u][i];
		if (j != fa) {
			dfs_len(j, u);
			int len = len1[j] + 1;
			if (len > len1[u]) len2[u] = len1[u], len1[u] = len, tmp[u] = j;
			else if (len > len2[u]) len2[u] = len;
		}
	}
	maxd = max(maxd, len1[u] + len2[u]);
}

void dfs_tofa(int u, int fa) {
	for (int i = 0; i < a[u].size(); i++) {
		int j = a[u][i];
		if (j != fa) { 
			tofa[j] = tofa[u] + 1;
			if (tmp[u] != j) tofa[j] = max(tofa[j], len1[u] + 1);
			else tofa[j] = max(tofa[j], len2[u] + 1);
			dfs_tofa(j, u);
		}
	}
}

int main() {
	cin >> n;
	for (int i = 0; i < n - 1; i++) {
		int x, b;
		cin >> x >> b;
		a[x].push_back(b);
		a[b].push_back(x);
	}
	dfs_len(0, -1);
	dfs_tofa(0, -1);
	for (int i = 0; i < n; i++) {
		int len[3] = { len1[i], len2[i], tofa[i] };
		sort(len, len + 3);
		if (len[1] + len[2] == maxd) cout << i << endl;
	}
	return 0;
}

T4 分组行动

coding...

posted @ 2024-10-16 22:19  Second_coming  阅读(45)  评论(0)    收藏  举报