L3 题解链接:https://blog.youkuaiyun.com/mldl_/article/details/123311743
注意题干隐含的条件
7-1 正整数A+B (15 分)
思路
输入一行字符串,再处理
AC代码
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int get_num(string s){
int len = s.size();
int res = 0;
for(int i = 0; i < len; i++){
int tmp = s[i] - '0';
if(tmp < 0 || tmp > 9) return -1;
else res = res * 10 + tmp;
}
if(res > 1000 || res < 1) return -1;
return res;
}
int main(int argc, char** argv) {
string s, a, b;
getline(cin, s);
int len = s.size(), f = 1;
for(int i = 0; i < len; i++){
if(s[i] == ' ' && f) f = 0;
else if(f) a += s[i];
else b += s[i];
}
int x = get_num(a);
int y = get_num(b);
if(x + y == -2) cout << "? + ? = ?" << endl;
else if(x == -1) cout << "? + " << y << " = ?" << endl;
else if(y == -1) cout << x << " + ? = ?" << endl;
else cout << x << " + " << y << " = " << x + y << endl;
return 0;
}
7-2 I Love GPLT (5 分)
思路
签到题。
AC代码
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main(int argc, char** argv) {
string s = "I Love GPLT";
int len = s.size();
for(int i = 0; i < len; i++) cout << s[i] << endl;
return 0;
}
7-3 出租 (20 分)
思路
给出现的数字按顺序编号,然后再按照题意输出即可。
AC代码
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main(int argc, char** argv) {
string s;
cin >> s;
string ss = s;
sort(ss.begin(), ss.end());
int n = unique(ss.begin(), ss.end()) - ss.begin();
cout << "int[] arr = new int[]{";
for(int i = n-1; i >= 0; i--){
cout << ss[i];
if(i == 0) cout << "};" << endl;
else cout << ",";
}
int len = s.size();
reverse(ss.begin(), ss.begin()+n);
cout << "int[] index = new int[]{";
for(int i = 0; i < len; i++){
for(int j = 0; j < n; j++){
if(s[i] == ss[j]){
cout << j;
if(i+1 == len) cout << "};" << endl;
else cout << ",";
break;
}
}
}
return 0;
}
7-4 判断素数 (10 分)
思路
O(根号n) 的时间复杂度判断素数,特判 0 和 1
AC代码
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main(int argc, char** argv) {
int ncase;
cin >> ncase;
while(ncase--){
long long n;
cin >> n;
int f = 1;
for(long long i = 2; i * i <= n; i++){
if(n % i == 0){
f = 0;
break;
}
}
if(n < 2) f = 0;
if(f) cout << "Yes" << endl;
else cout << "No" << endl;
}
return 0;
}
7-5 是不是太胖了 (5 分)
思路
按题意计算即可
AC代码
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main(int argc, char** argv) {
double num;
cin >> num;
num = (num - 100) * 0.9 * 2;
printf("%.1lf\n", num);
return 0;
}
7-6 一帮一 (15 分)
思路
暴力匹配即可。
AC代码
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
string name[55];
int flag[55];
int v[55] = {0};
int main(int argc, char** argv) {
int n;
cin >> n;
for(int i = 1; i <= n; i++) cin >> flag[i] >> name[i];
for(int i = 1; i <= n; i++){
if(v[i]) continue;
for(int j = n; j >= 1; j--){
if(v[j]) continue;
if(flag[i] + flag[j] == 1){
v[i] = v[j] = 1;
cout << name[i] << " " << name[j] << endl;
break;
}
}
}
return 0;
}
7-7 到底是不是太胖了 (10 分)
思路
分三段判断既可。
AC代码
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main(int argc, char** argv) {
int ncase;
cin >> ncase;
while(ncase--){
double h, w;
cin >> h >> w;
double tmp = (h - 100) * 0.9 * 2;
if(fabs(w - tmp) * 10 < tmp) cout << "You are wan mei!" << endl;
else if(w > tmp) cout << "You are tai pang le!" << endl;
else cout << "You are tai shou le!" << endl;
}
return 0;
}
7-8 Left-pad (20 分)
思路
字符串模拟。
AC代码
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main(){
int n; char c;
cin >> n >> c;
getchar();
string s;
getline(cin, s);
int len = s.size();
if(n <= len){
for(int i = len - n; i < len; i++) cout << s[i];
}
else{
int l = n - len;
for(int i = 1; i <= l; i++) cout << c;
cout << s << endl;
}
return 0;
}
7-9 红色警报 (25 分)
思路
并查集统计联通块的个数(无向图,在同一个联通块的点是一个集合,有相同的祖先)。
如果这个点不影响联通性,这个点将成为一个新的联通块,联通块的个数加一。
如果这个点影响联通性,不但这个点将成为一个新的联通块,而且原来的一个联通块将分裂成多个连通块。这时联通块的个数最少加 2.
如果删掉 B点,B 将成为一个新的联通快,联通块的个数变为 2。
如果删掉 A点,联通块的个数变为 4。
AC代码
#include <bits/stdc++.h>
#include <vector>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#define ll long long
#define chushi(a, b) memset(a, b, sizeof(a))
#define endl "\n"
const double eps = 1e-8;
const ll INF=0x3f3f3f3f3f3f3f3f;
const ll mod = 998244353;
const int maxn = 1e5 + 5;
using namespace std;
bool ma[505][505] = {0};
int f[505];
int find(int x){
if(f[x] == x) return x;
else return f[x] = find(f[x]);
}
void join(int x, int y){
int fx = find(x);
int fy = find(y);
if(fx != fy){
f[fx] = fy;
}
}
int main(){
int n, m;
cin >> n >> m;
int u, v;
for(int i = 1; i <= n; i++) f[i] = i;
for(int i = 1; i <= m; i++){
cin >> u >> v;
ma[u+1][v+1] = 1;
ma[v+1][u+1] = 1;
join(u+1, v+1);
}
int sum = 0;
for(int i = 1; i <= n; i++) if(f[i] == i) sum++;
int k, x;
cin >> k;
for(int i = 1; i <= k; i++){
cin >> x;
for(int i = 1; i <= n; i++) ma[i][x+1] = ma[x+1][i] = 0;
int num = 0;
for(int i = 1; i <= n; i++) f[i] = i;
for(int i = 1; i <= n; i++){
for(int j = i+1; j <= n; j++){
if(ma[i][j]) join(i, j);
}
}
for(int i = 1; i <= n; i++) if(f[i] == i) num++;
if(num > sum+1) cout << "Red Alert: City " << x << " is lost!" << endl;
else cout << "City " << x << " is lost." << endl;
sum = num;
}
if(k == n) cout << "Game Over." << endl;
return 0;
}
7-10 列车调度 (25 分)
思路
Dilworth定理:最少下降子序列个数等于最长上升子序列的长度。
证明自行百度。
这里要二分优化查找,不然会 TI 掉两个点。
AC代码
#include <bits/stdc++.h>
#include <vector>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#define ll long long
#define chushi(a, b) memset(a, b, sizeof(a))
#define endl "\n"
const double eps = 1e-8;
const ll INF=0x3f3f3f3f3f3f3f3f;
const ll mod = 998244353;
const int maxn = 1e5 + 5;
using namespace std;
int v[maxn];
int main(){
int n;
cin >> n;
int x;
for(int i = 1; i <= n; i++) v[i] = maxn;
for(int i = 1; i <= n; i++){
cin >> x;
int ind = lower_bound(v+1, v+1+n, x) - v;
v[ind] = x;
}
cout << lower_bound(v+1, v+1+n, maxn) - v - 1 << endl;
return 0;
}
7-11 互评成绩 (25 分)
思路
按照题意模拟即可。
AC代码
#include <bits/stdc++.h>
#include <vector>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#define ll long long
#define chushi(a, b) memset(a, b, sizeof(a))
#define endl "\n"
const double eps = 1e-8;
const ll INF=0x3f3f3f3f3f3f3f3f;
const ll mod = 998244353;
const int maxn = 1e5 + 5;
using namespace std;
vector<double> res;
double v[maxn];
int main(){
int n, k, m;
cin >> n >> k >> m;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= k; j++) cin >> v[j];
sort(v+1, v+1+k);
double sum = 0;
for(int j = 2; j < k; j++) sum += v[j];
res.push_back((sum / (1.0 * k - 2)));
}
sort(res.begin(), res.end());
for(int i = m; i >= 1; i--){
printf("%.3lf", res[n-i]);
if(i != 1) printf(" ");
else printf("\n");
}
return 0;
}
7-12 愿天下有情人都是失散多年的兄妹 (25 分)
思路
map 离散化编号。
map 存性别。
DFS 找祖先,让孩子指向父母,建图。
注意:父亲隐含是男性,母亲隐含是女性,不然会 wa
AC代码
#include <bits/stdc++.h>
#include <vector>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#define ll long long
#define chushi(a, b) memset(a, b, sizeof(a))
#define endl "\n"
const double eps = 1e-8;
const ll INF=0x3f3f3f3f3f3f3f3f;
const ll mod = 998244353;
const int maxn = 1e5 + 5;
using namespace std;
map<string, int> id;
int cnt = 0;
int get_id(string s){
if(id[s] == 0) return id[s] = ++cnt;
else return id[s];
}
int f[maxn];
int m[maxn];
map<string, char> sex;
int V[maxn];
int flag;
void DFS(int a, int d){
if(d > 4) return;
if(!flag) return;
if(a == -1) return;
if(V[a] != 0) flag = 0;
else V[a]++;
if(f[a] != -1) DFS(f[a], d+1);
if(m[a] != -1) DFS(m[a], d+1);
}
int main(){
chushi(f, -1); chushi(m, -1); id["-1"] = -1;
int n;
cin >> n;
string name, ff, mm; char se;
for(int i = 1; i <= n; i++){
cin >> name >> se >> ff >> mm;
f[get_id(name)] = get_id(ff);
m[get_id(name)] = get_id(mm);
if(ff != "-1") sex[ff] = '1';
if(mm != "-1") sex[mm] = '0';
sex[name] = se;
}
int k;
cin >> k;
while(k--){
string a, b;
cin >> a >> b;
if(sex[a] == sex[b]) cout << "Never Mind" << endl;
else{
flag = 1; chushi(V, 0);
DFS(get_id(a), 0);
DFS(get_id(b), 0);
if(flag) cout << "Yes" << endl;
else cout << "No" << endl;
}
}
return 0;
}