2019 ICPC 沈阳
F(签到)
图中找度数为1的点
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 2e5 + 50;
int n;
int cnt[MAXN];
int main()
{
scanf("%d", &n);
for(int i = 1;i < n; i++)
{
int u, v;
scanf("%d%d", &u, &v);
cnt[u]++;
cnt[v]++;
}
int res = 0;
for(int i = 1; i <= MAXN - 50; i++)
{
if(cnt[i] == 1) res ++;
}
printf("%d\n", res);
return 0;
}
A(set)
找每个数最前面比他大的数的最小值
set维护(二分查找)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
typedef long long ll;
const int MAXN = 1e5 + 50;
int n;
ll a[MAXN];
ll cnt[MAXN];
set<ll>s;
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++) cin >> a[i];
ll sum = 0;
for(int i = 1; i <= n; i++)
{
auto x = s.upper_bound(a[i]);
if(x != s.end()) sum += *x;
s.insert(a[i]);
}
printf("%lld\n", sum);
return 0;
}
J(二分)
题意:给定n种花与其数量,并给出一束花最多能有m枝不同的花,问最多能插几束花
对于一个特定的x束花,如果当前类型的话数量超过x,则最多贡献x,小于x则贡献 a [ i ] a[i] a[i]枝花。
进行累加,判断最后能否达到 x ∗ m x*m x∗m
二分查找x
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
typedef long long ll;
const int MAXN = 3e5 + 50;
int T;
ll n, m;
ll a[MAXN];
bool check(ll x)
{
ll lim = x * m, tot = 0;
for(int i = 1; i <= n; i++)
{
if(a[i] >= x) tot += x;
else tot += a[i];
}
if(tot < lim) return false;
else return true;
}
int main()
{
cin >> T;
while(T--)
{
scanf("%lld%lld", &n, &m);
ll sum = 0;
for(int i = 1; i <= n; i++)
{
cin >> a[i];
sum += a[i];
}
ll l = 0, r = sum / m + 1, ans = 0;
while(l <= r) // 注意需要等于号
{
ll mid = (l + r) / 2;
if(check(mid)) {
ans = max(ans, mid);
l = mid + 1;
}
else r = mid - 1;
}
printf("%lld\n", ans);
}
return 0;
}