10月16日 CSP-S

Second_coming發表於2024-10-16

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...