水题
C++ 1 2 3 4 5 6 7 void solve () { cin >> n >> s >> t; for (int i = 0 ; i < s.size (); i++) if (s[i] != t[i]) cnt++; cout << cnt; }
水题,就是个排名问题
C++ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 int n, p[N];PII peo[N]; bool cmp1 (PII x, PII y) { return p[x.first] > p[y.first]; } bool cmp2 (PII x, PII y) { return x.first < y.first; } void solve () { cin >> n; for (int i = 1 ; i <= n; i++) cin >> p[i], peo[i].first = i; sort (peo + 1 , peo + n + 1 , cmp1); int rank = 0 , cnt = 1 , last = 0 ; while (cnt <= n) { if (p[peo[cnt].first] == last) peo[cnt++].second = rank; else last = p[peo[cnt].first], peo[cnt].second = cnt, rank = cnt++; } sort (peo + 1 , peo + n + 1 , cmp2); for (int i = 1 ; i <= n; i++) cout << peo[i].second << endl; }
# 题目大意给你一个无向图,问要删除多少条边才能使得图中不存在环?
# 题解考察并查集 的题目,对于新进的一条边
如果两个端点在一个集合中,则这条边需被删去 如果不在,则是有效边 计算被删去的边的数量即可C++ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 int n, f[N], m, a, b;int find (int x) { if (x != f[x]) f[x] = find (f[x]); return f[x]; } void solve () { cin >> n >> m; for (int i = 1 ; i <= n; i++) f[i] = i; int cnt = 0 ; while (m--) { cin >> a >> b; int fa = find (a), fb = find (b); if (fa == fb) cnt++; else f[fa] = fb; } cout << cnt << endl; }
# 题目大意毁了,理解题目大意用了半年 给定一个 n n n ,和序列 A = ( a 1 , . . . a 2 N ) A=(a_1,...a_{2N}) A = ( a 1 , . . . a 2 N ) ,其中每个 1 , . . . , n 1,...,n 1 , . . . , n 都出现两次 问,能找到多少对情侣对 ( a , b ) (a,b) ( a , b )
情侣对是什么? 在原序列中,a , b a,b a , b 的两个出现位置不邻接 可以通过交换这四个数的位置,使得 a , b a,b a , b 分别的两个数邻接 # 题解# 错解只考虑了不连在一起的情况,但对于 1 2 1 2 3 4 3 4
这样的, 1 2 1 2
就会被算 1 2
, 2 1
, 1 2
三次
C++ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 int n, peo[N];void solve () { cin >> n; vector<vector<int >> g (n + 10 ); for (int i = 1 ; i <= 2 * n; i++) { cin >> peo[i]; g[peo[i]].push_back (i); } int cnt = 0 ; for (int i = 1 ; i <= 2 * n - 1 ; i++) { int a = peo[i], b = peo[i + 1 ]; if (a == b) continue ; int l1 = g[a][0 ], l2 = g[a][1 ], r1 = g[b][0 ], r2 = g[b][1 ]; if (l1 + 1 == l2 || r1 + 1 == r2) continue ; if (abs (l1 - r1) == 1 && abs (l2 - r2) == 1 ) cnt++; } cout << cnt / 2 << endl; return ; }
# 正解为了避免上面的情况,可以利用
C++ 1 2 3 vector<int > kk = {l1, l2, r1, r2}; sort (kk.begin (), kk.end ());res.insert ({min (a, b), max (a, b)});
统计不同数对,时间复杂度也是在可接受的范围之内
C++ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 int n, peo[N];void solve () { cin >> n; vector<vector<int >> g (n + 10 ); set<PII> res; for (int i = 1 ; i <= 2 * n; i++) { cin >> peo[i]; g[peo[i]].push_back (i); } int cnt = 0 ; for (int i = 1 ; i <= 2 * n - 1 ; i++) { int a = peo[i], b = peo[i + 1 ]; int l1 = g[a][0 ], l2 = g[a][1 ], r1 = g[b][0 ], r2 = g[b][1 ]; if (a == b || l1 + 1 == l2 || r1 + 1 == r2) continue ; vector<int > kk = {l1, l2, r1, r2}; sort (kk.begin (), kk.end ()); if (kk[0 ] + 1 == kk[1 ] && kk[2 ] + 1 == kk[3 ]) res.insert ({min (a, b), max (a, b)}); } cout << res.size () << endl; return ; }
还需要多注意的是,题目数据范围到了
1 e 5 1e5 1 e 5 ,一开始用的
vector<int> g[N]
结果直接爆了,能开
vector<vector<int>> g(n + 1)
还是尽可能用后者吧