OR97. 狙击手
描述
输入描述
第一行一个正整数N 接下来一行N个正整数,第i个数字Ti表示第i个狙击手瞄准了第Ti个狙击手,注意可能存在Ti=i输出描述
两行,第一行是最少存活的狙击手的数量,第二行是最多存活的狙击手的数量示例1
输入:
8 2 3 2 2 6 7 8 5
输出:
3 5
说明:
样例解释: 最少存活的情况:2开枪消灭3,1开枪消灭2,7开枪消灭8,6开枪消灭7,5开枪消灭6,最后1, 4, 5存活。 最多存活的情况:1开枪消灭2,5开枪消灭6,7开枪消灭8,最后1,3,4,5,7存活。 数据约定: 20% N≤10 50% N≤10000 100% N≤1000000,1≤Ti≤NC++ 解法, 执行用时: 130ms, 内存消耗: 12500KB, 提交时间: 2020-12-28
#include <iostream> #include <vector> #include <string> #include <algorithm> #include <map> #include <set> #include <sstream> #include<queue> #include<bits/stdc++.h> using namespace std; int target[1000005]; bool visit[1000005]; int father[1000005]; int main() { ios::sync_with_stdio(false); cin.tie(0); int n, ans; int the_next; cin >> n; for (int i = 1; i < n + 1; i++) { cin >> target[i]; father[target[i]]++; } for (int i = 1; i < n + 1; i++) { if (father[i] == 0) { visit[i] = true; ans++; the_next = target[i]; while (!visit[the_next]) { visit[the_next] = true; the_next = target[the_next]; } } } for (int i = 1; i < n + 1; i++) { if (visit[i] || i == target[i])continue; visit[i] = true; ans++; the_next = target[i]; while (!visit[the_next]) { visit[the_next] = true; the_next = target[the_next]; } } cout << ans << endl; memset(visit, false, sizeof(visit)); ans = 0; queue<int> line; for (int i = 1; i < n + 1; i++) if (father[i] == 0) line.push(i); int head; while (!line.empty()) { head = line.front(); line.pop(); visit[head] = true; ans++; the_next = target[head]; if (!visit[the_next]) { visit[the_next] = true; the_next = target[the_next]; father[the_next]--; if (father[the_next] == 0) { line.push(the_next); } } } int lens; for (int i = 1; i < n + 1; i++) { if (visit[i] || i == target[i])continue; visit[i] = true; lens = 1; the_next = target[i]; while (!visit[the_next]) { lens += 1; visit[the_next] = true; the_next = target[the_next]; } ans += (lens >> 1); } cout << ans << endl; return 0; }
C++ 解法, 执行用时: 134ms, 内存消耗: 12536KB, 提交时间: 2020-10-31
#include <iostream> #include <vector> #include <string> #include <algorithm> #include <map> #include <set> #include <sstream> #include<queue> #include<bits/stdc++.h> using namespace std; int target[1000005]; bool visit[1000005]; int father[1000005]; int main() { ios::sync_with_stdio(false); cin.tie(0); int n, ans; int the_next; cin >> n; for (int i = 1; i < n + 1; i++) { cin >> target[i]; father[target[i]]++; } for (int i = 1; i < n + 1; i++) { if (father[i] == 0) { visit[i] = true; ans++; the_next = target[i]; while (!visit[the_next]) { visit[the_next] = true; the_next = target[the_next]; } } } for (int i = 1; i < n + 1; i++) { if (visit[i] || i == target[i])continue; visit[i] = true; ans++; the_next = target[i]; while (!visit[the_next]) { visit[the_next] = true; the_next = target[the_next]; } } cout << ans << endl; memset(visit, false, sizeof(visit)); ans = 0; queue<int> line; for (int i = 1; i < n + 1; i++) if (father[i] == 0) line.push(i); int head; while (!line.empty()) { head = line.front(); line.pop(); visit[head] = true; ans++; the_next = target[head]; if (!visit[the_next]) { visit[the_next] = true; the_next = target[the_next]; father[the_next]--; if (father[the_next] == 0) { line.push(the_next); } } } int lens; for (int i = 1; i < n + 1; i++) { if (visit[i] || i == target[i])continue; visit[i] = true; lens = 1; the_next = target[i]; while (!visit[the_next]) { lens += 1; visit[the_next] = true; the_next = target[the_next]; } ans += (lens >> 1); } cout << ans << endl; return 0; }