A Sexy Primes
签到题,素数不需要用筛法,直接O(sqrt(n))即可。
#include<iostream>
using namespace std;
bool check(int a) {
if (a < 2)
return false;
for (int i = 2; i * i <= a; i++)
if (a % i == 0)
return false;
return true;
}
int main() {
int n;
cin >> n;
if (check(n - 6) && check(n)) {
cout << "Yes" << endl << n - 6;
} else if (check(n) && check(n + 6)) {
cout << "Yes" << endl << n + 6;
} else {
cout << "No" << endl;
for (int i = n + 1;; i++) {
//注意
if (check(i) && (check(i - 6) || check(i + 6))) {
cout << i;
break;
}
}
}
return 0;
}
B Anniversary
热身题,字符串处理,使用集合判断。
#include<iostream>
#include<unordered_set>
#include<string>
#define ac cin.tie(0);cin.sync_with_stdio(0);
using namespace std;
unordered_set<string> set;
int main() {
ac
int n, cnt = 0;
string s, old_al = "99999999999999999999999999999", ans = "9999999999999999999999999999999";
cin >> n;
while (n--) {
cin >> s;
set.insert(s);
//记录最老的校友,出生年份越小越老
if (s.substr(6, 8) < old_al.substr(6, 8))
old_al = s;
}
cin >> n;
while (n--) {
cin >> s;
if (set.count(s))
++cnt;
///记录最老的来宾
if (s.substr(6, 8) < ans.substr(6, 8))
ans = s;
}
cout << cnt << endl;
if (cnt) {
cout << old_al;
} else {
cout << ans;
}
return 0;
}
C Telefraud Detection
稍难,图论+并查集,还有要理解题意(个人认为PAT最难的点)。
#include<iostream>
#include<vector>
#include<algorithm>
#define ac cin.tie(0);cin.sync_with_stdio(0);
using namespace std;
const int MAXN = 1010;
int G[MAXN][MAXN], pre[MAXN];
bool vis[MAXN];
vector<int> v;
int n, m, k;
int find(int a) {
return pre[a] == a ? a : pre[a] = find(pre[a]);
}
int main() {
ac
int a, b, c;
cin >> k >> n >> m;
while (m--) {
cin >> a >> b >> c;
G[a][b] += c;
}
for (int i = 1; i <= n; i++) {
int cnt = 0, bt = 0;
for (int j = 1; j <= n; j++) {
//短通话有效
if (G[i][j] && G[i][j] <= 5) {
++cnt;
//记录回电次数
if (G[j][i])
++bt;
}
}
//可疑诈骗电话加入v
if (cnt > k && bt * 5 <= cnt)
v.push_back(i);
}
//没有可疑人员
if (!v.size()) {
cout << "None";
return 0;
}
//准备并查集
for (int i:v)
pre[i] = i;
for (int i = 0; i < v.size(); i++) {
for (int j = i + 1; j < v.size(); j++) {
//双方都有通话
if (G[v[j]][v[i]] && G[v[i]][v[j]]) {
int a = find(v[j]);
int b = find(v[i]);
pre[a] = b;
}
}
}
for (int i = 0; i < v.size(); i++) {
if (vis[v[i]])
continue;
if (i)
cout << endl;
vector<int> tmp;
tmp.push_back(v[i]);
int a = find(v[i]);
//查找同伙
for (int j = i + 1; j < v.size(); j++)
if (find(v[j]) == a) {
vis[v[j]] = true;
tmp.push_back(v[j]);
}
for (int j = 0; j < tmp.size(); j++) {
if (j)
cout << " ";
cout << tmp[j];
}
}
return 0;
}
D Structure of a Binary Tree
要细心,做对不容易,建树、DFS,处理每个输入。(PS. 满二叉树的定义有歧义。)
#include<iostream>
#include<string>
using namespace std;
const int MAXN = 1010;
int post[MAXN], in[MAXN];
int le[MAXN], ri[MAXN], map[MAXN], dep[MAXN];
int n, m, k;
//建树
int buildTree(int a, int b) {
if (a > b)
return -1;
int pos = map[post[k]];
--k;
ri[in[pos]] = buildTree(pos + 1, b);
le[in[pos]] = buildTree(a, pos - 1);
return in[pos];
}
//确定是否为满二叉树并且确定节点的层次
void dfs(int root, bool &op, int t) {
if (root == -1)
return;
int tt = 0;
if (le[root] == -1)++tt;
if (ri[root] == -1)++tt;
if (tt & 1)
op = false;
dep[root] = t;
dfs(le[root], op, t + 1);
dfs(ri[root], op, t + 1);
}
int main() {
string s;
cin >> n;
for (int i = 0; i < n; i++)
cin >> post[i];
for (int i = 0; i < n; i++) {
cin >> in[i];
map[in[i]] = i;
}
k = n - 1;
int root = buildTree(0, n - 1);
//判断是否为满二叉树
//是否为满二叉树
bool op = true;
dfs(root, op, 0);
cin >> m;
getchar();
while (m--) {
getline(cin, s);
bool ans = false;
if (s == "It is a full tree") {
if (op)
ans = true;
} else if (s[s.length() - 1] == 't') {
int a;
sscanf(s.c_str(), "%d is the root", &a);
if (a == root)
ans = true;
} else if (s[s.length() - 1] == 's') {
int a, b;
sscanf(s.c_str(), "%d and %d are siblings", &a, &b);
for (int i = 0; i < n; i++)
if ((le[in[i]] == a && ri[in[i]] == b) || (le[in[i]] == b && ri[in[i]] == a)) {
ans = true;
break;
}
} else if (s.find("parent") != string::npos) {
int a, b;
sscanf(s.c_str(), "%d is the parent of %d", &a, &b);
if (le[a] == b || ri[a] == b)
ans = true;
} else if (s.find("left") != string::npos) {
int a, b;
sscanf(s.c_str(), "%d is the left child of %d", &a, &b);
if (le[b] == a)
ans = true;
} else if (s.find("right") != string::npos) {
int a, b;
sscanf(s.c_str(), "%d is the right child of %d", &a, &b);
if (ri[b] == a)
ans = true;
} else {
int a, b;
sscanf(s.c_str(), "%d and %d are on the same level", &a, &b);
if (dep[a] == dep[b])
ans = true;
}
if (ans)
cout << "Yes";
else
cout << "No";
if (m)
cout << endl;
}
return 0;
}