持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情
AcWing——第72场周赛
4624. 最小值 - AcWing题库
问题解析
直接比较a,b,(a+b)/3的大小,输出最小的即可。
AC代码
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include <random>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<fstream>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#include<bitset>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#define endl '\n'
#define int ll
#define PI acos(-1)
#define INF 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 4e5 + 50;
void solve()
{
int a, b, c;
cin >> a >> b;
c = (a + b) / 3;
cout << min(a, min(b, c)) << endl;
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
4625. 压缩文件 - AcWing题库
问题解析
贪心。
先计算一下一个都不压缩需要的空间sum,然后看是不是小于等于m,如果是,说明一个都不压缩也能放得下,输出0。不然,我们用一个数组,记录bi-ai的值,即将这个文件压缩后能节省的空间。并对他们降序排序。每次取能节省最多的文件来压缩:sum-(ai-bi)。压缩到sum小于m为止。如果所有文件都压缩了,sum还是大于m,输出-1。
AC代码
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include <random>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<fstream>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#include<bitset>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#define endl '\n'
#define int ll
#define PI acos(-1)
#define INF 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 4e5 + 50;
void solve()
{
int n, m, sum = 0, cnt = 0, x, y;
cin >> n >> m;
vector<int>v(n);
for (int i = 0; i < n; i++)
{
cin >> x >> y;
sum += x;
v[i] = x - y;
}
sort(v.begin(), v.end(), greater<int>());
int idx = 0;
while (idx<n&&sum > m)
{
sum -= v[idx++];
cnt++;
}
if (sum <= m)cout << cnt;
else cout << -1;
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t = 1;
//cin >> t;
while (t--)
{
solve();
}
return 0;
}
4626. 最小移动距离 - AcWing题库
问题解析
我心态爆炸,因为没有判断当前点是否走过,一直t在最后一个测试例。
这题的意思就是:判断这些点是否都能组成一个个的环,如果是就输出这些环的长度的最小公倍数,反之输出-1。
然后就是正常的建单向图,如果有ai等于i的情况,我们直接记录这个环的大小是1即可。
再dfs求得每个环的大小:记录递归的次数,如果重复走到起点,说明成环,如果不成环,返回0。
- 如果返回0,说明不是所有的点都能组成环,输出-1.
- 如果返回偶数,那么环的大小要减半。比如1->2->3->4->1,那么1的目标点就可以是3,而不非要是自己,所以路径大小减半。
- 如果返回奇数,直接记录下来。
然后对所有记录的环的大小,求他们的最小公倍数。
AC代码
//求最大公约数
int gcd(int a, int b)
{
return b==0?a:gcd(b, a % b);
}
int n;
//存图,其实不用这么麻烦,主要是习惯
vector<int>tree[N];
//记录这个点是否走过
bool st[150];
//x是当前点,y是起点,len是递归次数
int dfs(int x, int y, int len)
{
int z = 0;
if (x == y && len != 0)
{
return len;
}
//因为除了起点以外,每个点都只可能走一次,如果这个点不是起点还走了两次,必定不是环
if (st[x] && x != y)return 0;
st[x] = true;
for (auto i : tree[x])
{
z = dfs(i, y, len + 1);
}
return z;
}
void solve()
{
int x;
cin >> n;
vector<int>res;
for (int i = 1; i <= n; i++)
{
cin >> x;
if (x != i)
tree[i].push_back(x);
else
{
res.push_back(1);
st[i] = true;
}
}
for (int i = 1; i <= n; i++)
{
//如果当前点没有走过,那么它可以当作环的起点
if (st[i] == false)
{
//求环长
int ans = dfs(i, i, 0);
//不是环,输出-1
if (ans == 0)
{
cout << -1 << endl;
return;
}
else
{
//偶数长度要减半
if (ans % 2 == 0)ans /= 2;
res.push_back(ans);
}
}
}
//计算最小公倍数
x = 1;
for (auto i : res)
{
x = x / gcd(max(i, x), min(i, x)) * i;
}
cout << x;
}