思路:为了防止任何连续的三个数单调,排序后可按照一半单增一半单减交叉排列
#include<bits/stdc++.h> #define fora(i, a, b) for(int i = a; i <= b; i++) #define fors(i, a, b) for(int i = a; i >= b; i--) #define ll long long using namespace std; int t, n; ll a[100]; int main(){ cin >> t; while(t--){ cin >> n; memset(a, 0, sizeof(0)); fora(i, 1, 2 * n) cin >> a[i]; sort(a + 1, a + 1 + 2 * n); fora(i, 1, n) cout << a[i] << " " << a[2 * n + 1 - i] << " "; cout << endl; } return 0; }
思路:首先发现 n > 3 n > 3 n>3的 n n n位 1 1 1都可以由 11 11 11和 111 111 111表示,例: 1111 = 11 ∗ 101 1111 = 11 * 101 1111=11∗101,所以只探究 11 11 11和 111 111 111即可。接着发现任意满足条件的 n n n都可以只由 0 − 10 0 - 10 0−10个 111 111 111和剩下的 11 11 11表示
#include<bits/stdc++.h> #define fora(i, a, b) for(int i = a; i <= b; i++) #define fors(i, a, b) for(int i = a; i >= b; i--) #define ll long long using namespace std; ll t, n; int main(){ cin >> t; while(t--){ int flg = 0; cin >> n; fora(i, 0, 10){ int m = n; if(m >= i * 111) m -= i * 111; if(m % 11 == 0){ flg = 1; break; } } cout << (flg == 1 ? "YES" : "NO") << endl; } }
思路:一道后悔式贪心,当遇到负数时能收则收,不能收想办法扔一个再收。于是可以用优先队列按顺序记录收下的负数,每次不能再收时都扔掉消耗最大的(数值最小的)来在 c n t cnt cnt不变的情况下使 a n s ans ans尽可能大
#include<bits/stdc++.h> #define fora(i, a, b) for(int i = a; i <= b; i++) #define fors(i, a, b) for(int i = a; i >= b; i--) #define ll long long using namespace std; int n, a[200005], cnt = 0; ll ans = 0; priority_queue <int, vector<int>, greater<int> > q; int main(){ cin >> n; fora(i, 1, n){ cin >> a[i]; if(a[i] >= 0){ ans += a[i]; cnt++; } else if(ans + a[i] >= 0){ ans += a[i], cnt++; q.push(a[i]); } else if(!q.empty() && a[i] > q.top() && ans - q.top() + a[i] >= 0){//若q为空,q.top()会出错!!! ans += a[i] - q.top(); q.pop(), q.push(a[i]); } } cout << cnt << endl; }
变强了再做。。。
变强了再做。。。
变强了再做。。。