By xiaruize
分情况考虑
- a=0或b=0时,一次
- a×d=b×c,两分数已经相等,答案为0
- (a×d,b×c)有非1倍的倍数关系时,答案为1
- 其他情况,答案为2
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
#include <bits/stdc++.h> using namespace std; #define int long long #define ull unsigned long long #define ALL(a) (a).begin(), (a).end() #define pb push_back #define mk make_pair #define pii pair<int, int> #define pis pair<int, string> #define sec second #define fir first #define sz(a) int((a).size()) #define rep(i, x, y) for (int i = x; i <= y; i++) #define repp(i, x, y) for (int i = x; i >= y; i--) #define Yes cout << "Yes" << endl #define YES cout << "YES" << endl #define No cout << "No" << endl #define NO cout << "NO" << endl #define debug(x) cerr << #x << ": " << x << endl #define double long double const int INF = 0x3f3f3f3f; const int MOD = 1000000007; const int N = 2e5 + 10;
int t; int a, b, c, d;
signed main() { cin >> t; while (t--) { cin >> a >> b >> c >> d; if (a * d == c * b) cout << "0" << endl; else if (a == 0 || c == 0 || (a * d) % (b * c) == 0 || (b * c) % (a * d) == 0) cout << "1" << endl; else cout << "2" << endl; } return 0; }
|
求出序列最大值mx,次大值smx,最小值mi,次小值smi
可以发现,一定存在一组[l,r]使得最大值和次大值在两个部分,最小值和次小值在两个部分
所以答案为mx+smx−mi−smi
可以O(n)求得
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
#include <bits/stdc++.h> using namespace std; #define int long long #define ull unsigned long long #define ALL(a) (a).begin(), (a).end() #define pb push_back #define mk make_pair #define pii pair<int, int> #define pis pair<int, string> #define sec second #define fir first #define sz(a) int((a).size()) #define rep(i, x, y) for (int i = x; i <= y; i++) #define repp(i, x, y) for (int i = x; i >= y; i--) #define Yes cout << "Yes" << endl #define YES cout << "YES" << endl #define No cout << "No" << endl #define NO cout << "NO" << endl #define debug(x) cerr << #x << ": " << x << endl #define double long double const int INF = 0x3f3f3f3f; const int MOD = 1000000007; const int N = 1e5 + 10;
int t; int n; int a[N]; int mx, mp, mxx, mpp, mi, mip, mii, mipp;
void solve() { cin >> n; for (int i = 1; i <= n; i++) cin >> a[i]; mx = mp = mxx = mpp = mi = mip = mii = mipp = 0; mi = mii = INF; for (int i = 1; i <= n; i++) { if (a[i] > mx) { mxx = mx; mpp = mp; mx = a[i]; mpp = i; } else if (a[i] > mxx) { mxx = a[i]; mpp = i; } if (a[i] < mi) { mii = mi; mipp = mip; mi = a[i]; mip = i; } else if (a[i] < mii) { mii = a[i]; mipp = i; } } cout << mx + mxx - mi - mii << endl; }
signed main() { cin >> t; while (t--) solve(); return 0; }
|
首先,考虑如果有一个L形的0在一开始就存在,那么一定可以每次只取一个1
所以要最小化第一个L中1的个数,可以O(nm)的扫一遍整个数组来达成
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
|
#include <bits/stdc++.h> using namespace std; #define int long long #define ull unsigned long long #define ALL(a) (a).begin(), (a).end() #define pb push_back #define mk make_pair #define pii pair<int, int> #define pis pair<int, string> #define sec second #define fir first #define sz(a) int((a).size()) #define rep(i, x, y) for (int i = x; i <= y; i++) #define repp(i, x, y) for (int i = x; i >= y; i--) #define Yes cout << "Yes" << endl #define YES cout << "YES" << endl #define No cout << "No" << endl #define NO cout << "NO" << endl #define debug(x) cerr << #x << ": " << x << endl #define double long double const int INF = 0x3f3f3f3f; const int MOD = 1000000007; const int N = 2e5 + 10;
int n, m; int t; int a[505][505];
void solve() { cin >> n >> m; int res = 0; for (int i = 1; i <= n; i++) { string s; cin >> s; for (int j = 1; j <= m; j++) { a[i][j] = s[j - 1] - '0'; if (a[i][j]) res++; } } int mi = INF; for (int i = 1; i < n; i++) { for (int j = 1; j < m; j++) { mi = min(mi, min(min(a[i][j] + a[i + 1][j] + a[i][j + 1], a[i][j] + a[i + 1][j] + a[i + 1][j + 1]), min(a[i + 1][j] + a[i + 1][j + 1] + a[i][j + 1], a[i][j] + a[i][j + 1] + a[i + 1][j + 1]))); } } if (mi == 0) mi = 1; cout << res - mi + 1 << endl; }
signed main() { cin >> t; while (t--) solve(); return 0; }
|
很容易想到一个 O(N2) 的 dp.
但是,可以发现转移并不需要从前面的n个转移过来,而是只需要从前面的400个转移到当前位即可
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
#include <bits/stdc++.h> using namespace std; #define int long long #define ull unsigned long long #define ALL(a) (a).begin(), (a).end() #define pb push_back #define mk make_pair #define pii pair<int, int> #define pis pair<int, string> #define sec second #define fir first #define sz(a) int((a).size()) #define rep(i, x, y) for (int i = x; i <= y; i++) #define repp(i, x, y) for (int i = x; i >= y; i--) #define Yes cout << "Yes" << endl #define YES cout << "YES" << endl #define No cout << "No" << endl #define NO cout << "NO" << endl #define debug(x) cerr << #x << ": " << x << endl #define double long double const int INF = 0x3f3f3f3f; const int MOD = 1000000007; const int N = 3e5 + 10;
int t; int n; int a[N]; int dp[N];
void chkmax(int &x, int y) { if (y > x) x = y; }
void solve() { memset(dp, 0, sizeof(dp)); cin >> n; for (int i = 0; i < n; i++) { cin >> a[i]; dp[i] = 1; } int res = 0; for (int i = 0; i < n; i++) { for (int j = i - 1; j >= max(0ll, i - 400); j--) { if ((a[j] ^ i) < (a[i] ^ j)) chkmax(dp[i], dp[j] + 1); } chkmax(res, dp[i]); } cout << res << endl; }
signed main() { cin >> t; while (t--) solve(); return 0; }
|