PAT (Advanced Level) 1140~1143:1140模拟 1141模拟 1142暴力 1143 BST+LCA
1140?Look-and-say Sequence(20?分)
題意:觀察序列D, D1, D111, D113, D11231, D112213111, ...,顯然后一個串是對前一個串每一小段連續相同的字母及其個數的描述。例如,D112213111是對D11231的描述,原因是在D11231中,依次出現了1個D(即D1),2個1(即12),1個2(即21),1個3(即31),1個1(即11), 連起來即為D112213111。給定D,問符合該規律的序列中第N個數是多少?
分析:
1、C++寫法:按題意模擬即可。
#include<cstdio> #include<cstring> #include<cstdlib> #include<string> #include<algorithm> #include<iostream> using namespace std; int main(){int D, N;while(scanf("%d%d", &D, &N) == 2){char tmp[1010];sprintf(tmp, "%d", D);string s = string(tmp);string ans;N--;while(N--){int len = s.size();int cnt = 0;ans = "";for(int i = 0; i < len - 1; ++i){if(s[i] == s[i + 1]){++cnt;}else{ans += s[i];sprintf(tmp, "%d", cnt + 1);ans += string(tmp);cnt = 0;}}if(s[len - 2] == s[len - 1]){ans += s[len - 2];sprintf(tmp, "%d", cnt + 1);ans += string(tmp);}else{ans += s[len - 1];ans += "1";}s = ans;}printf("%s\n", s.c_str());}return 0; }2、python寫法:itertools.groupby函數可以將字符串中連續相同的字母分組。
import itertools D, N = map(int, input().split()) s = str(D) for _ in range(N - 1):ans = ''for char, lst in itertools.groupby(s):ans += charans += str(len(tuple(lst)))s = ans print(s)1141?PAT Ranking of Institutions(25?分)
題意:根據給定的信息計算學校的排名,并按規定的順序輸出即可。
#include<cstdio> #include<cstring> #include<cstdlib> #include<string> #include<algorithm> #include<map> #include<iostream> using namespace std; const int MAXN = 100000 + 10; map<string, int> mp; int cnt; struct Node{int B, A, T, tot, sum, _rank;string school;bool operator < (const Node&rhs)const{return sum > rhs.sum || sum == rhs.sum && tot < rhs.tot || sum == rhs.sum && tot == rhs.tot && school < rhs.school;} }num[MAXN]; int getId(string s){if(mp.count(s)) return mp[s];return mp[s] = ++cnt; } int main(){int N;while(scanf("%d", &N) == 1){cnt = 0;mp.clear();string Rank, School;int Score;for(int i = 0; i < N; ++i){cin >> Rank >> Score >> School;int len = School.size();for(int j = 0; j < len; ++j){if(School[j] >= 'A' && School[j] <= 'Z') School[j] += 32;}int id = getId(School);if(Rank[0] == 'B') num[id].B += Score;else if(Rank[0] == 'A') num[id].A += Score;else if(Rank[0] == 'T') num[id].T += Score;++num[id].tot;num[id].school = School;}for(int i = 1; i <= cnt; ++i){double tmp = num[i].B / 1.5 + num[i].A + num[i].T * 1.5;num[i].sum = (int)tmp;}sort(num + 1, num + cnt + 1);printf("%d\n", cnt);printf("1 %s %d %d\n", num[1].school.c_str(), num[1].sum, num[1].tot);num[1]._rank = 1;int kase = 1;for(int i = 2; i <= cnt; ++i){if(num[i].sum != num[i - 1].sum){num[i]._rank = i;printf("%d %s %d %d\n", num[i]._rank, num[i].school.c_str(), num[i].sum, num[i].tot);}else{num[i]._rank = num[i - 1]._rank;printf("%d %s %d %d\n", num[i]._rank, num[i].school.c_str(), num[i].sum, num[i].tot);}}}return 0; }1142?Maximal Clique(25?分)
題意:如果一個無向子圖中任意兩個不同的點都直接相鄰,則稱其為clique;若該clique不能通過增加其他任何點來使其仍是clique,則稱其為maximal clique。給定一個無向圖,判斷給定的點集是否滿足maximal clique。
分析:
1、最多200個點,記錄邊的信息,暴力即可。
2、對于判斷是否為maximal clique,則暴力枚舉每個可能增加的點,判斷其是否與給定點集中的所有點都直接相鄰即可。
#include<cstdio> #include<cstring> #include<cstdlib> #include<string> #include<algorithm> #include<map> #include<iostream> #include<vector> using namespace std; const int MAXN = 200 + 10; int Edge[MAXN][MAXN]; vector<int> v; bool vis[MAXN]; int Nv, Ne; bool judge(){int len = v.size();for(int i = 0; i < len; ++i){for(int j = i + 1; j < len; ++j){int tmpx = v[i];int tmpy = v[j];if(!Edge[tmpx][tmpy] && !Edge[tmpy][tmpx]){return false;}}}return true; } string solve(){int len = v.size();for(int i = 1; i <= Nv; ++i){if(!vis[i]){bool ok = true;for(int j = 0; j < len; ++j){int tmpx = v[j];if(!Edge[i][tmpx] && !Edge[tmpx][i]){ok = false;break;}}if(ok) return "Not Maximal";}}return "Yes"; } int main(){while(scanf("%d%d", &Nv, &Ne) == 2){memset(Edge, 0, sizeof Edge);int a, b;for(int i = 0; i < Ne; ++i){scanf("%d%d", &a, &b);Edge[a][b] = Edge[b][a] = 1;}int M;scanf("%d", &M);while(M--){memset(vis, false, sizeof vis);v.clear();int K, x;scanf("%d", &K);while(K--){scanf("%d", &x);v.push_back(x);vis[x] = true;}bool ok = judge();if(!ok){printf("Not a Clique\n");}else{printf("%s\n", solve().c_str());}}}return 0; }1143?Lowest Common Ancestor(30?分)
題意:給定一個二叉搜索樹,求給定的一對點的最近公共祖先。樹的鍵值在int范圍內。
分析:
1、常規思路:離散化樹的鍵值,建BST,在樹上求LCA,結果超時。
2、假設待求lca的一對點分別為u和v,遍歷給定BST的前序遍歷數組,若當前遍歷的點值在u和v之間或者值等于u或v,則其必為u和v的最近公共祖先。
#include<cstdio> #include<cstring> #include<cstdlib> #include<string> #include<algorithm> #include<map> #include<iostream> #include<vector> #include<set> using namespace std; const int MAXN = 10000 + 10; int a[MAXN]; map<int, int> mp; bool judge(int tmp, int x, int y){return tmp == x || tmp == y || (tmp > x && tmp < y) || (tmp > y && tmp < x); } int main(){int M, N;while(scanf("%d%d", &M, &N) == 2){mp.clear();for(int i = 0; i < N; ++i){scanf("%d", &a[i]);mp[a[i]] = 1;}int x, y;while(M--){scanf("%d%d", &x, &y);if(!mp.count(x) && !mp.count(y)){printf("ERROR: %d and %d are not found.\n", x, y);}else if(!mp.count(x)){printf("ERROR: %d is not found.\n", x);}else if(!mp.count(y)){printf("ERROR: %d is not found.\n", y);}else{for(int i = 0; i < N; ++i){if(judge(a[i], x, y)){if(a[i] == x){printf("%d is an ancestor of %d.\n", a[i], y);}else if(a[i] == y){printf("%d is an ancestor of %d.\n", a[i], x);}else{printf("LCA of %d and %d is %d.\n", x, y, a[i]);}break;}}}}}return 0; }
轉載于:https://www.cnblogs.com/tyty-Somnuspoppy/p/9493757.html
總結
以上是生活随笔為你收集整理的PAT (Advanced Level) 1140~1143:1140模拟 1141模拟 1142暴力 1143 BST+LCA的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在sql当中为了让数据做缓存做with
- 下一篇: MFC-CString与int互相转化