日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【编程训练-考研上机模拟】综合模拟2-2019浙大上机模拟(晴神)

發布時間:2025/3/15 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【编程训练-考研上机模拟】综合模拟2-2019浙大上机模拟(晴神) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

A - next[i]

Problem Description

在字符串匹配的KMP算法中有一個重要的概念是next數組,求解它的過程讓不少同學傷透了心。next數組的直接語義其實是:使“長度為L的前綴”與“長度為L的后綴”相同的最大L,且滿足條件的前后綴不能是原字符串本身。

例如對字符串"ababa"來說,長度為1的前綴與后綴都是"a",它們相同;長度為2的前綴與后綴分別是"ab"和"ba",它們不相同;長度為3的前綴與后綴都是"aba",它們相同;長度為4的前綴與后綴分別是"abab"和"baba",它們不相同。因此對字符串"ababa"來說,使“長度為L的前綴”與“長度為L的后綴”相同的最大L是3。

現在我們把這個最大的L值稱為原字符串S的next值。在此概念的基礎上,對給定的字符串S,下標為從1到N,那么next[i]就是指子串S[1...i]的next值。

現在給定一個字符串,下標從1到N,然后給一個下標i,求next[i]。

Input

每個輸入文件一組數據。

只有一行,輸入一個僅由小寫字母組成的長度為N(1<=N<=100)的字符串、與一個下標i(1<=i<=N)。

Output

一個整數,即next[i]。

Sample Input 1

ababa 5

Sample Output 1

3

Sample Input 2

ababab 4

Sample Output 2

2

Sample Input 3

ab 2

Sample Output 3

0

分析:掌握具體算法即可,算法詳解見KMP算法

#include<bits/stdc++.h> using namespace std; void buildNext(string str, int nt[]){int len = str.size();nt[0] = -1;int t = nt[0], j = 0;while(j < len - 1){if(t < 0 || str[j] == str[t]){nt[++j] = ++t;}else{t = nt[t];}} } int main(){int nt[110];string str;cin>>str;buildNext(str, nt);int index;cin>>index;cout<<nt[index - 1] + 1<<endl;return 0; }

B - 鏈表重排

Problem Description

給定一條單鏈表,將鏈表結點進行頭尾交錯重新排序,即如果一條單鏈表為 L1 -> L2 -> ... -> L(n-1) -> Ln ,那么重新排序完的結果是 L1 -> Ln -> L2 -> L(n-1) -> L3 -> L(n-2) -> ...

Input

每個輸入文件中一組數據。

第一行給出結點的總個數N(0<N<10^5)和單鏈表的第一個結點的地址。所有結點的地址要么是一個五位正整數,要么是用-1表示的空地址NULL。然后是N行,表示N個結點,每行的格式為

Address Data Next

其中Address為結點地址(不足5位的高位用零填充至5位),Data為結點的數據域(絕對值不超過10^5的整數),Next為結點的指針域(即下一個結點的地址)。數據保證Address不等于-1。

Output

輸出按題目要求重新排序后的單鏈表。第一行為重新排序后單鏈表上結點的個數、第一個結點的地址。

之后每行一個結點,輸出格式與輸入相同,結點輸出順序為單鏈表連接順序。

Sample Input

5 11111 33333 0 44444 22222 2 33333 11111 5 22222 05689 8 -1 44444 6 05689

Sample Output

5 11111 11111 5 05689 05689 8 22222 22222 2 44444 44444 6 33333 33333 0 -1

分析:

1. 鏈表的長度要自己計算,不是所有的節點都會用到

2. 鏈表可能是空的

#include<bits/stdc++.h> using namespace std; const int nmax = 100010; int data[nmax], nt[nmax], lt[nmax]; int main(){int n, head;cin>>n>>head;for(int i = 0; i < n; i++){int addr;cin>>addr;cin>>data[addr]>>nt[addr];}int len = 0;while(head != -1){lt[len++] = head;head = nt[head];}vector<int>ans;int i = 0, j = len - 1;while(i <= j){ans.push_back(lt[i++]);if(i < j)ans.push_back(lt[j--]);}if(ans.size() == 0){printf("0 -1");return 0;}printf("%d %05d\n", ans.size(), ans[0]);for(int i = 0; i < ans.size() - 1; ++i){printf("%05d %d %05d\n", ans[i], data[ans[i]], ans[i + 1]);}printf("%05d %d -1\n", ans.back(), data[ans.back()]);return 0; }

C - 極大匹配

Problem Description

對給定的無向圖G=(V,E),如果邊集E'滿足:(1)E'是E的子集;(2)E'中的任意兩條邊都沒有公共頂點,那么稱邊集E'為圖G的一個匹配(Matching)。而如果往E'中增加任意一條在E中但不在E'中的邊,都會導致E'不再是圖G的匹配,那么稱E'為圖G的一個極大匹配(Maximal Matching)。
(以上定義引自https://en.wikipedia.org/wiki/Matching_(graph_theory))

根據上面的定義,請判斷一些給定的邊集是否是給定的無向圖的極大匹配。

Input

每個輸入文件一組數據。

第一行兩個整數N、M(1<=N<=1000, 0<=M<=N*(N-1)/2),表示頂點數和邊數,假設所有頂點的編號為1到N。

接下來M行,每行兩個正整數u、v(1<=u,v<=N, u!=v),表示一條邊的兩個端點編號。

然后一個正整數K(K<=10),表示查詢個數。

接下來為K個查詢,每個查詢第一行為一個正整數L,表示待查詢邊集的邊數,接下來L行每行兩個正整數,表示一條邊的兩個端點編號。數據保證每個查詢中相同的邊只會出現一次,且所有邊都在圖中存在。

Output

每個查詢輸出一行,如果給定的邊集是極大匹配,那么輸出Yes;如果它是匹配但不是極大匹配,那么輸出Not Maximal;如果不是匹配,那么輸出Not a Matching。

Sample Input

4 4 1 2 1 3 2 3 2 4 4 1 2 3 1 1 3 2 1 2 2 4 2 1 3 2 4

Sample Output

Yes Not Maximal Not a Matching Yes

Solution

#include<bits/stdc++.h> using namespace std; const int nmax = 1010; bool vis[nmax], G[nmax][nmax], tempG[nmax][nmax]; struct node{int u, v; }; int main(){int n, m, K, L;vector<node>E;cin>>n>>m;fill(G[0], G[0] + nmax * nmax, false);for(int i = 0; i < m; ++i){int u, v;cin>>u>>v;G[u][v] = G[v][u] =true;E.push_back({u, v});}cin>>K;for(int i =0; i < K; ++i){vector<node>tempE;fill(vis, vis + nmax, false);fill(tempG[0], tempG[0] + nmax * nmax, false);cin>>L;bool flag = true;for(int j = 0; j < L; ++j){int u, v;cin>>u>>v;if(G[u][v] == false)flag = false;if(vis[u] == true || vis[v] == true)flag = false;tempG[u][v] = tempG[v][u] = true;tempE.push_back({u, v});vis[u] = vis[v] = true;}if(flag == false)printf("Not a Matching\n");else{for(int j = 0; j < E.size(); ++j){int u = E[j].u, v = E[j].v;if(tempG[u][v] == false){if(vis[u] == false && vis[v] == false){flag = false;break;}}}if(flag == true)printf("Yes\n");else printf("Not Maximal\n");}}return 0; }

D - 關鍵路徑

Problem Description

給定一個有N個頂點、M條邊的有向圖,頂點下標為從1到N,每條邊都有邊權。判斷這個有向圖是否是有向無環圖,如果是的話,請處理K個查詢,每個查詢為圖中的一條邊,求這條邊的最早發生時間和最晚發生時間。最后再輸出圖中的所有關鍵路徑。

Input

每個輸入文件中一組數據。

第一行為兩個整數N、M,表示有向無環圖的頂點數和邊數(1<=N<=1000, 0<=M<=N*(N-1)),頂點編號為從1到N。

接下來M行,每行為三個正整數u、v、w(1<=u,v<=N,0<w<=20,u!=v),分別表示有向邊的起點、終點、邊權。數據保證不會有兩條起點和終點都相同的邊。

然后是一個正整數K(1<=K<=1000),表示查詢個數。

接著是K行,每行為兩個正整數u、v,分別表示查詢邊的起點和終點。數據保證查詢邊一定是圖上存在的邊。

Output

如果給出的圖不是有向無環圖,那么在一行里輸出NO,后面的查詢結果和關鍵路徑均不需要輸出;

如果給出的圖是有向無環圖,那么在一行里輸出YES,接著輸出下面的內容:

每個查詢一行,輸出查詢邊的最早發生時間和最晚發生時間;

之后一行輸出一個整數:關鍵路徑上的邊權之和;

最后若干行輸出所有關鍵路徑,每行表示其中一條,格式為用->連接的頂點編號。注意,如果有兩條關鍵路徑a[1]->a[2]->...->a[k]->a[k+1]->...與b[1]->b[2]->...->b[k]->[k+1]->...,滿足a[1]==b[1]、a[2]==b[2]、...、a[k]==b[k]、a[k+1]<b[k+1],那么把關鍵路徑a優先輸出。數據保證關鍵路徑條數不超過10000條。

Sample Input 1

4 5 1 2 3 1 3 2 1 4 5 2 4 1 3 4 3 2 1 3 2 4

Sample Output 1

YES 0 0 3 4 5 1->3->4 1->4

Sample Input 2

3 3 1 2 3 2 3 1 3 2 2 2 1 2 2 3

Sample Output 2

NO

分析:

1.多個有向圖

2.多起點、多匯點

3.圖中存在孤立點,此時入度也為0

求關鍵路徑時,將存關鍵路徑上的邊而非關鍵活動,使用鄰接表而非鄰接矩陣

#include<bits/stdc++.h> using namespace std; const int nmax = 1010; struct node{int v, w; }; vector<node>G[nmax]; vector<int>activity[nmax]; int n, m, inDeg[nmax] = {0}, inDegOrigin[nmax] = {0}; int ve[nmax], vl[nmax]; int e[nmax][nmax], l[nmax][nmax]; stack<int>topOrder; bool topologicalSort(){queue<int>q;for(int i = 1; i <= n; ++i){if(inDeg[i] == 0)q.push(i);}while(!q.empty()){int u = q.front();q.pop();topOrder.push(u);for(int i = 0; i < G[u].size(); ++i){int v = G[u][i].v;inDeg[v]--;if(inDeg[v] == 0)q.push(v);ve[v] = max(ve[v], ve[u] + G[u][i].w);}}if(topOrder.size() == n)return true;else return false; } int criticalPath(){fill(ve, ve + nmax, 0);if(topologicalSort() == false)return -1;int maxLen = -1;for(int i = 1; i <= n; ++i){if(ve[i] > maxLen)maxLen = ve[i];}fill(vl, vl + nmax, maxLen);while(!topOrder.empty()){int u = topOrder.top();topOrder.pop();for(int i = 0; i < G[u].size(); ++i){int v = G[u][i].v;vl[u] = min(vl[u], vl[v] - G[u][i].w);}}for(int u = 1; u <= n; ++u){for(int i = 0; i < G[u].size(); ++i){int v = G[u][i].v, w = G[u][i].w;e[u][v] = ve[u];l[u][v] = vl[v] - w;if(e[u][v] == l[u][v])activity[u].push_back(v);}}return maxLen; } vector<int>path; void dfs(int u){if(activity[u].size() == 0){path.push_back(u);int flag = 0;for(int x : path){if(flag == 1)printf("->");printf("%d", x);flag = 1;}printf("\n");path.pop_back();return;}path.push_back(u);sort(activity[u].begin(), activity[u].end());for(int x : activity[u]){dfs(x);}path.pop_back(); } int main(){scanf("%d%d", &n, &m);for(int i = 0; i < m; ++i){int u, v, w;scanf("%d%d%d", &u, &v, &w);G[u].push_back({v, w});inDeg[v]++;inDegOrigin[v]++;}int maxLen = criticalPath();if(maxLen == -1)printf("NO\n");else{printf("YES\n");int k;scanf("%d", &k);for(int i = 0; i < k; ++i){int u, v;scanf("%d%d", &u, &v);printf("%d %d\n", e[u][v], l[u][v]);}printf("%d\n", maxLen);for(int i =1; i <= n; ++i){if(inDegOrigin[i] == 0 && activity[i].size() != 0)dfs(i);}}return 0; }

轉載于:https://www.cnblogs.com/vinnson/p/10844947.html

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的【编程训练-考研上机模拟】综合模拟2-2019浙大上机模拟(晴神)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。