Codeforces Round #746 (Div. 2)
思路:
这题刚开始用暴力做的,然后TLE了,然后就思考这个h有没有别的方法处理。先从大到小排序,然后分两种情况,首先,如果h比一倍的前两项的和还小,那就再看h是不是比第一项还小,如果比第一项还小或和第一项相等,那答案就是1。如果比第一项大一点,那答案就是2。
然后第二种情况,h比前两项的和大,就看是前两项的几倍,先求出这个倍数,因为每一倍都包含两项,所以答案res先是两倍的倍数,然后再看,如果h正好是前两项和的倍数,那答案就是res。如果不正好,再看是不是就大了一点点,大的比第一项小,如果是,res就加1。不然如果大的比第一项大,说明还得有第二项,res是+2。
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> #include <queue> #define x first #define y second using namespace std; typedef long long LL; typedef pair<int, int>PII; const int N = 200010; const int MOD = 1000000007; int a[N], b[N]; int main() { ios::sync_with_stdio(false); cin.tie(0); int T; cin >> T; while (T--) { int n, h; cin >> n >> h; for (int i = 1; i <= n; i++) cin >> a[i]; sort(a + 1, a + 1 + n, greater<int>()); int res = 0; int tmp = a[1] + a[2]; int k1 = h / tmp; if (k1 == 0) { if (h - a[1] <= 0) res = 1; else res = 2; } else if (k1 > 0) { int t = h - k1 * tmp; if (t == 0) res = 2 * k1; else if (t > 0) { if (t - a[1] <= 0) res = 2 * k1 + 1; else res = 2 * k1 + 2; } } cout << res << endl; } return 0; }
思路:
我们手算模拟一下几个样例,可以发现当x比较小时,数组一定能随便排。而随着x逐渐增大,可以发现从中间开始逐渐有项没法被排序(交换),不难发现x的临界值是n/2,即当x > n/2时,中间有一段没法排,而两边随便排,而两边即前n - x个数和后n - x个数,所以中间这一段数就是从第n - x + 1个数到第x个数,因此我们只要保证中间的这一段所有的数都是和sort过的数是对应的就行。
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> #include <queue> #define x first #define y second using namespace std; typedef long long LL; typedef pair<int, int>PII; const int N = 200010; const int MOD = 1000000007; int a[N], tmp[N]; int main() { ios::sync_with_stdio(false); cin.tie(0); int T; cin >> T; while (T--) { int n, x; cin >> n >> x; for (int i = 1; i <= n; i++) cin >> a[i], tmp[i] = a[i]; sort(a + 1, a + 1 + n); bool flag = true; for (int i = n - x + 1; i <= x; i++) if (a[i] != tmp[i]) { flag = false; break; } if (flag) cout << "YES" << endl; else cout << "NO" << endl; } return 0; }

浙公网安备 33010602011771号