Codeforces Round #748 (Div. 3)
A. Elections
思路分析:
- 令当前值比最大值大即可,如果最大值是它自己,就输出\(0\)
代码
#include <bits/stdc++.h>
using namespace std;
pair<int, int> a[3];
int ans[3];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
for (int i = 0; i < 3; i++)
cin >> a[i].first, a[i].second = i;
sort(a, a + 3);
for (int i = 0; i < 3; i++)
{
if (i == 0)
{
ans[a[i].second] = a[2].first - a[0].first + 1;
}
else if (i == 1)
{
ans[a[i].second] = a[2].first - a[1].first + 1;
}
else
{
if (a[2].first == a[1].first)
{
ans[a[i].second] = 1;
}
else
ans[a[i].second] = 0;
}
}
for (int i = 0; i < 3; i++)
{
cout << ans[i] << ' ';
}
cout << endl;
}
return 0;
}
B. Make it Divisible by 25
思路分析:
- 一开始以为和上次make power of 2一样,然后发现不对劲,想到了结论,25是5的倍数,那么我们剩下的数最后一位必定为5或者0,所以我们一直删到最后一位为5或者0为止。
- 然后如果为25的倍数的话,末尾两位必定是25,50,75,00,所以我们就分情况取最小值即可。
- 其实官方题解的最简单,我就建议不要看我这个做法了。
代码
#include <bits/stdc++.h>
using namespace std;
int a[2] = {2, 7};
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
string s;
cin >> s;
string c = s;
int mincnt = 0;
//以5为最后一位
for (int i = s.size() - 1; i >= 0; i--)
{
if (s[i] != '5')
{
s.erase(i);
mincnt++;
}
//找到5
else
break;
}
for (int i = s.size() - 2; i >= 0; i--)
{
if (s[i] != '2' && s[i] != '7')
{
mincnt++;
s.erase(i);
}
else
break;
}
int temp = 0;
for (int i = c.size() - 1; i >= 0; i--)
{
if (c[i] != '0')
{
c.erase(i);
temp++;
}
//找到5
else
break;
}
for (int i = c.size() - 2; i >= 0; i--)
{
if (c[i] != '5' && c[i] != '0')
{
temp++;
c.erase(i);
}
else
break;
}
cout << min(mincnt, temp) << endl;
}
return 0;
}
C. Save More Mice
思路分析:
- 这题其实就是贪心吧,让离洞最近的老鼠先逃即可,因为老鼠和猫的相对速度为\(1\)。
- 注意更新猫的位置即可。
代码
#include <bits/stdc++.h>
using namespace std;
vector<int> a;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
a.clear();
int n, k;
cin >> n >> k;
for (int i = 0; i < k; i++)
{
int x;
cin >> x;
a.push_back(x);
}
sort(a.begin(), a.end());
int ans = 0;
int x = 0;
for (int i = a.size() - 1; i >= 0; i--)
{
if (x < a[i])
{
x += (n - a[i]);
ans++;
}
else
break;
}
cout << ans << endl;
}
return 0;
}
D1. All are Same
思路分析:
- 因为最后要把所有数变为一个数,那么肯定是把所有数变成当前数组的最小值即可。
- 那么如何求这个减去的数的最大值呢?
- 实际上也就是所有数和最小值的GCD了。
代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
sort(a.begin(), a.end());
int x = a[0];
int ans = 0;
for (int i = 0; i < n; i++)
{
ans = __gcd(ans, a[i] - x);
}
if (ans != 0)
cout << ans << endl;
else
{
cout << "-1" << endl;
}
}
return 0;
}
D2. Half of Same
思路分析:
- 我们可以知道当且仅当当前数组中已经有\(n / 2\)个数相同输出\(-1\)。
- 我们枚举每一个数,也就是说把其他数变为它需要减去多少值保存一下,然后记录原数组中已经有多少个数与它相同,再因数分解一下这个差值,然后遍历它的差值的因数,取使得因数的个数加上原本和它一样的数的个数大于\(n / 2\)的最大的因数即可。
代码
#include <bits/stdc++.h>
using namespace std;
set<int> divide(int x)
{
set<int> q;
for (int i = 1; i * i <= x; i++)
{
if (x % i == 0)
{
q.insert(i);
q.insert(x / i);
}
}
return q;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
int k = -1;
for (int i = 0; i < a.size(); i++)
{
int minv = a[i];
int same = 0;
vector<int> d;
for (int j = 0; j < a.size(); j++)
{
if (a[j] == minv)
same++;
else if (a[j] > minv)
{
d.push_back(a[j] - minv);
}
}
if (same >= n / 2)
{
k = INT_MAX;
break;
}
map<int, int> mp;
for (auto x : d)
{
for (auto xx : divide(x))
{
mp[xx]++;
}
}
for (auto x : mp)
{
if (x.second + same >= n / 2)
{
k = max(k, x.first);
}
}
}
cout << (k == INT_MAX ? -1 : k) << endl;
}
return 0;
}
E. Gardener and Tree
思路分析:
- 一开始以为暴力能过就写了个暴力然后T了。然后看了下题解,原来是反向的,也就是说我们也是模拟一下删点过程(把这棵树删完),然后统计一下是在第几轮删去的这个点,最后把删去轮数和\(k\)比较即可。
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 4e5 + 10;
int degree[maxn];
vector<int> e[maxn];
int n, k, ans;
int vis[maxn];
int dis[maxn];
int main()
{
int t;
cin >> t;
while (t--)
{
memset(vis, 0, sizeof(vis));
memset(degree, 0, sizeof(degree));
memset(dis, 0, sizeof(dis));
cin >> n >> k;
ans = n;
for (int i = 1; i <= n; i++)
{
e[i].clear();
}
for (int i = 1; i < n; i++)
{
int u, v;
cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
degree[u] += 1;
degree[v] += 1;
}
queue<int> q;
for (int i = 1; i <= n; i++)
{
if (degree[i] == 1)
{
q.push(i);
vis[i] = 1;
dis[i] = 1;
}
}
while (!q.empty())
{
int x = q.front();
q.pop();
for (int j = 0; j < e[x].size(); j++)
{
int u = e[x][j];
if (vis[u])
continue;
degree[u]--;
if (degree[u] == 1)
{
q.push(u);
vis[u] = 1;
dis[u] = dis[x] + 1;
}
}
}
int ans = 0;
for (int i = 1; i <= n; i++)
{
if (dis[i] > k)
{
ans++;
}
}
cout << ans << endl;
}
return 0;
}