A AvtoBus
点此进入题面
题意:
给定一个数 n
,如果它能被 m
个 4
或 6
组合而成,输出 m
的最小值和最大值。
如果不能被若干 4
或 6
组成,输出 -1。
思路:
首先,当 n
为奇数 或 n
小于 4
的时候,显然是不能被 4
和 6
组合而成的,这需要进行特判。
具体思路见代码注释。
代码:
#define _CRT_SECURE_NO_WARNINGS 1
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef map<int, int> mi;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
#define pb push_back
#define pp pop_back
#define x first
#define y second
const int N = 2e5 + 10;
signed main()
{
int T = 1;
cin>>T;
while (T--)
{
int n; cin >> n;
if (n < 4 || n & 1)
{
puts("-1");
continue;
}
int mn, mx;
if (n % 4 == 0) //能被 4 整除的话
{
mx = n / 4; //显然 n / 4 为 max
if (n % 6 == 0) //如同时可以被 6 整除
{
mn = n / 6; //那么n / 6 为 min
cout << mn << ' ' << mx << '\n';
continue;
}
else //如果不能同时被 6 整除,只需带点贪心的思想暴力求解 min 即可
{
int t = n, cnt = 0;
while (t % 6 && t >= 0)
{
t -= 4;
++cnt;
}
mn = cnt + t / 6;
cout << mn << ' ' << mx << '\n';
continue;
}
}
//下面情况思想与上一致
if (n % 6 == 0)
{
mn = n / 6;
int t = n, cnt = 0;
while (t % 4 && t >= 0)
{
t -= 6;
++cnt;
}
mx = cnt + t / 4;
cout << mn << ' ' << mx << '\n';
continue;
}
//如果既不能被 4 整除又不能被 6 整除,那么需要贪心求解 min 和 max
//下面是求 min
int t = n;
int cnt = 0;
bool ok1 = false, ok2 = false;
while (t % 6 && t >= 0) //贪心
{
t -= 10; //4、6 捆绑一组,和为 10,每次循环删去一组
cnt += 2; //每删去一组 10,形成的个数要加 2
if (t % 6 == 0) ok1 = true; //成功找到最小值
}
if (ok1) mn = cnt + t / 6;
//下面是求 max
int tt = n;
int num = 0;
while (tt % 4 && tt >= 0)
{
tt -= 10;
num += 2;
if (tt % 4 == 0) ok2 = true;
}
if (ok2) mx = num + tt / 4;
if (!ok1 && !ok2) { puts("-1"); continue; } //如 min 和 max 均未找到,即无法用 4 和 6 组合,不过显然这种情况是不存在的,因为只要是大于等于4的偶数,就可以被 4 和 6 组合而成!
if (!ok1 && ok2)
{
mn = mx;
cout << mn << ' ' << mx << '\n';
continue;
}
if (ok1 && !ok2)
{
mx = mn;
cout << mn << ' ' << mx << '\n';
continue;
}
cout << mn << ' ' << mx << '\n';
}
return 0;
}