牛客IOI周赛22-普及组
链接:https://ac.nowcoder.com/acm/contest/11038
A. 战争尾声
思路:枚举从(1, 1)至(200,200)所有的点,判断是否存在一个点到其他所有点距离均相等,然而这道题实际上不一定要开double 用int一样可以过,因为在计算距离的时候保留距离的平方值进行比较也是可以允许的,时间复杂度:O(n * 200^2).
100分代码:
#include<iostream>
#include<cmath>
#define debug(x) cout << "***" << x << endl
const int N = 205;
const double eps = 1e-4;
using namespace std;
int n, cnt = 0, flag = 1;
struct Node
{
double x, y;
}a[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n;
for(int i = 1; i <= n; i++)
cin >> a[i].x >> a[i].y;
for(int i = 1; i <= 200; i++)
{
for(int j = 1; j <= 200; j++)
{
flag = 1;
double res = sqrt(pow(fabs(a[1].x - 1.0 * i), 2) + pow(fabs(a[1].y - 1.0 * j), 2));
for(int k = 1; k <= n; k++)
{
double dis = sqrt(pow(fabs(a[k].x - 1.0 * i), 2) + pow(fabs(a[k].y - 1.0 * j), 2));
// cout << i << " " << j << endl;
// debug(dis);
if(fabs(res - dis) > eps)
{
flag = 0;
break;
}
}
if(flag)
{
cout << i << " " << j << endl;
break;
}
}
if(flag) break;
}
if(!flag) cout << "War is cruel." << endl;
return 0;
}
B. 签订协议
思路:
- 60分解法:利用优先队列把每次序列中最大值找出后,从该最大值开始往下访问不断更新并判断该序列的最大值(不断去掉该轮最大值)是否在该轮最大值之后,时间复杂度:O(n^2logn).
- 100分解法:将序列中从大到小排序,并记录每个数的位置,从前向后访问,若当前访问到国家的位置比下一个即将访问到国家的位置大,说明,高战力的国家在一个低战力国家之后,那么肯定需要再进行一轮传递,时间复杂度达到:O(nlogn)
60分代码:
#include<iostream>
#include<queue>
#include<vector>
#define debug(x) cout << "***" << x << endl
using namespace std;
typedef pair<int, int> PII;
const int N = 8e5 + 5;
int n;
vector<PII> a;
priority_queue<PII, vector<PII>, less<PII> > heap;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n;
for(int i = 0; i < n; i++)
{
int x;
cin >> x;
a.push_back({x, i});
heap.push({x, i});
}
int num = 0;
while(heap.size())
{
num ++;
PII temp = heap.top();
heap.pop();
int val = temp.first, pos = temp.second;
//debug(val);
for(int i = pos + 1; i < n; i++)
{
PII nowNode = heap.top();
if(a[i].first == nowNode.first)
{
val = nowNode.first;
pos = nowNode.second;
heap.pop();
}
//debug(val);
}
}
cout << num <<endl;
return 0;
}
100分代码:
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 8e5 + 5;
int n;
struct Node
{
int val, pos;
}a[N];
bool cmp(Node a, Node b)
{
return a.val > b.val;
}
int main()
{
cin >> n;
for(int i = 1; i <= n; i++)
{
cin >> a[i].val;
a[i].pos = i;
}
sort(a + 1, a + 1 + n, cmp);
int cnt = 0;
for(int i = 1; i <= n - 1; i++)
{
if(a[i].pos > a[i+1].pos)
cnt ++;
}
cout << cnt + 1;
return 0;
}
C. (暂时懵逼)
D. 路线规划
思路:最小生成数的权值 * 2即为答案,权值需要开LL,不然只能过60%
Prime代码:
#include<iostream>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> PII;
const int N = 2e5 + 5;
int n, m;
int dis[N], st[N];
vector<PII>g[N];
priority_queue<PII, vector<PII>, greater<PII>> heap;
LL prime()
{
LL cnt = 0, sum = 0;
dis[1] = 0;
heap.push({0, 1}); //权值、顶点
while(heap.size() && cnt < n)
{
PII temp = heap.top();
heap.pop();
LL nowNode = temp.second, nowVal = temp.first;
if(st[nowNode]) continue;
cnt ++;
st[nowNode] = 1;
sum += nowVal;
for(int i = 0; i < g[nowNode].size(); i++)
{
LL nextNode = g[nowNode][i].first, nextVal = g[nowNode][i].second;
if(dis[nextNode] > nextVal)
{
dis[nextNode] = nextVal;
heap.push({nextVal, nextNode});
}
}
}
return sum;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
memset(dis, 0x3f, sizeof dis);
memset(st, 0, sizeof st);
cin >> n >> m;
for(int i = 1; i <= m; i++)
{
LL u, v, x;
cin >> u >> v >> x;
g[u].push_back({v, x});
g[v].push_back({u, x});
}
cout << prime() * 2 << endl;
return 0;
}
Kruaskal代码:
#include<iostream>
#include<algorithm>
#define debug(x) cout << "***" << x << endl
using namespace std;
typedef long long LL;
const int N = 2e6 + 5;
const int M = 2e5 + 5;
LL par[M];
int n, m;
struct Edge
{
LL a, b , w;
}e[N];
bool cmp(Edge x, Edge y)
{
return x.w < y.w;
}
LL find(LL x)
{
return par[x] == x ? x : par[x] = find(par[x]);
}
void merge(LL x, LL y)
{
par[find(x)] = find(y);
}
LL kruskal()
{
sort(e + 1, e + m + 1, cmp);
LL cnt = 0, sum = 0;
for(int i = 1; i <= m; i++)
{
LL a = e[i].a, b = e[i].b, w = e[i].w;
if(find(a) != find(b))
{
merge(a, b);
cnt ++;
sum += w;
}
if(cnt == n - 1) break;
}
return sum;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n >> m;
for(int i = 1; i <= n; i++)
par[i] = i;
for(int i = 1; i <= m; i++)
cin >> e[i].a >> e[i].b >> e[i].w;
cout << kruskal() * 2 << endl;
return 0;
}

浙公网安备 33010602011771号