1. 程式人生 > 實用技巧 >requests介面測試-headers

requests介面測試-headers

前言

只做了 A、B、C 三題。= =,D 的 dp 沒寫出來,貪了好久。

比賽連結

A. Bad Triangle

題目大意

在給定 \(n\) 個數裡選擇出三個數,使得其不能組成三角形

分析

三角形的組成條件為任意兩邊和大於第三邊。不妨把 \(n\) 個數按照升序排列(題目預設升序),然後取前面最小的兩個為兩個邊,計算它們的和。再從第三個開始找,找到大於等於和的邊就是答案。找不到就輸出 \(-1\)

程式碼

#include <bits/stdc++.h>
#define lowbit(x) ((x)&(-x))
#define mem(i, a) memset(i, a, sizeof(i))
#define sqr(x) ((x)*(x))
#define ls(x) (x << 1)
#define rs(x) (x << 1 | 1)
typedef long long ll;
const double eps = 1e-8;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const int maxn = 1e5 + 7;
using namespace std;
int arr[maxn];
int main(void){
#ifdef ljxtt
freopen("data.in", "r", stdin);
#endif
    int T; scanf("%d", &T);
    while(T--){
        int n; scanf("%d", &n);
        for(int i = 0; i < n; i++) scanf("%d", &arr[i]);
        int sum = arr[0] + arr[1];
        int inx = -1;
        for(int i = 2; i < n; i++){
            if(arr[i] >= sum){
                inx = i;
                break;
            }
        }
        if(inx == -1)
            puts("-1");
        else
            printf("1 2 %d\n", inx + 1);
    }
    return 0;
}

B. Substring Removal Game

題目大意

A 和 B兩個人玩遊戲,A先行。

遊戲規則為:給一段 01 串,每次操作都可以將一段連續相同的字元去掉,所得到的分數為去掉1的個數。當字串為空時停止遊戲。

A、B兩人都按照對自己最優的策略走,問A能得到的最大的分數是多少。

分析

顯然,去掉一段相同的 0 並沒有什麼卵用。所以,貪心地取連續最長的 1 即可。

程式碼

#include <bits/stdc++.h>
#define lowbit(x) ((x)&(-x))
#define mem(i, a) memset(i, a, sizeof(i))
#define sqr(x) ((x)*(x))
#define ls(x) (x << 1)
#define rs(x) (x << 1 | 1)
typedef long long ll;
const double eps = 1e-8;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const int maxn = 1e5 + 7;
using namespace std;
char s[maxn];
vector<int> arr;
int main(void){
#ifdef ljxtt
freopen("data.in", "r", stdin);
#endif
    int T; scanf("%d", &T);
    while(T--){
        scanf("%s", s);
        int len = strlen(s), cnt = 0;
        for(int i = 0; i < len; i++){
            if(s[i] == '1'){
                cnt++;
            }else{
                if(cnt != 0) arr.push_back(cnt);
                cnt = 0;
            }
        }
        if(cnt != 0) arr.push_back(cnt);
        sort(arr.begin(), arr.end(), greater<int> ());
        int ans = 0;
        for(int i = 0; i < arr.size(); i += 2) ans += arr[i];
        printf("%d\n", ans);
        arr.clear();
    }
    return 0;
}

C. Good Subarrays

題目大意

給定一個序列,詢問有多少個區間滿足:

\[\sum_{i = l}^{r}a_i = r - l + 1 \]

分析

用字首和表示上式為:

\[\begin{aligned} S(r) - S(l - 1) &= r - l + 1 \\ S(r) - r &= S(l - 1) - (l - 1)\\ f(r) &= f(l - 1) \end{aligned} \]

其中 \(f(x) = S(x) - x\),且 \(f(0) = 0\)

所以,也就是在所有的 \(f(x)\) 裡任意取出兩個相同的數字,詢問方案數。

統計一下相同數字的個數,用組合數算一下 \(C_n^2\)

就行了。

程式碼

#include <bits/stdc++.h>
#define lowbit(x) ((x)&(-x))
#define mem(i, a) memset(i, a, sizeof(i))
#define sqr(x) ((x)*(x))
#define ls(x) (x << 1)
#define rs(x) (x << 1 | 1)
typedef long long ll;
const double eps = 1e-8;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const int maxn = 1e5 + 7;
using namespace std;
ll arr[maxn];
map<ll, int> ma;
int main(void){
#ifdef ljxtt
freopen("data.in", "r", stdin);
#endif
    int T; scanf("%d", &T);
    while(T--){
        int n; scanf("%d", &n);
        for(int i = 1; i <= n; i++) scanf("%1lld", &arr[i]);
        for(int i = 1; i <= n; i++) arr[i] += arr[i - 1];
        for(int i = 1; i <= n; i++) arr[i] -= i;
        for(int i = 0; i <= n; i++) ma[arr[i]]++;
        ll ans = 0;
        for(auto it: ma){
            if(it.second > 1) ans += 1ll * it.second * (it.second - 1) / 2; 
        }
        printf("%lld\n", ans);
        ma.clear();
    }
    return 0;
}

D. Colored Rectangles

題目大意

給定 R、G、B對的紅色、綠色、藍色的木棒,對應顏色的第 i 對的長度為 ri,gi,bi。你可以進行如下操作:

在兩種不同的顏色裡各選出一對,使得它們組成一個長方形,並將矩形的面積加入到答案裡。

題目要求使得最後的答案最大。

分析

這種題目要麼貪心,要麼dp。

很顯然有個貪心的想法,就是把三種木棒混合在一起,按長度排序。然後從大到小列舉木棍,再在剩下的木棍裡選出顏色不同但最大的木棍組成矩形,加入到答案裡。列舉一遍就是答案。但這樣有一個問題就是下面這樣一個樣例:

1 1 2
1
1
1 1

上面這個樣例就有可能使得 R 和 G 配對,然後剩下的兩個 B 沒辦法配對。最優的答案是 R 和 B 配對,G 和 B 配對。所以上面這個貪心不成立。

所以我們考慮一下dp。先把三種不同的木棍按長度降序排列,定義 \(dp[i][j][k]\) 為 R、G、B分別用了 i,j,k 個木棍所取得的最大答案,那麼就有轉移方程為:

\[\begin{array} \\ dp[i][j][k] = \max(&dp[i - 1][j - 1][k] + R[i]\times G[i], \\ &dp[i - 1][j][k - 1] + R[i] \times B[i], \\&dp[i][j - 1][k - 1] + G[i] \times B[i]) \end{array} \]

初值為 \(dp[0][0][0] = 0\)

程式碼

#include <bits/stdc++.h>
#define lowbit(x) ((x)&(-x))
#define mem(i, a) memset(i, a, sizeof(i))
#define sqr(x) ((x)*(x))
#define ls(x) (x << 1)
#define rs(x) (x << 1 | 1)
typedef long long ll;
const double eps = 1e-8;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const int maxn = 2e2 + 7;
using namespace std;
ll dp[maxn][maxn][maxn];
int arr[3][maxn];
int main(void){
#ifdef ljxtt
freopen("data.in", "r", stdin);
#endif
    int num[3]; for(int i = 0; i < 3; i++) scanf("%d", &num[i]);
    for(int i = 0; i < 3; i++){
        for(int j = 0; j < num[i]; j++)
            scanf("%d", &arr[i][j]);
        sort(arr[i], arr[i] + num[i], greater<int> ());
    }
    ll ans = 0;
    for(int i = 0; i <= num[0]; i++)
        for(int j = 0; j <= num[1]; j++)
            for(int k = 0; k <= num[2]; k++){
                dp[i + 1][j + 1][k] = max(dp[i + 1][j + 1][k], dp[i][j][k] + 1ll * arr[0][i] * arr[1][j]);
                dp[i + 1][j][k + 1] = max(dp[i + 1][j][k + 1], dp[i][j][k] + 1ll * arr[0][i] * arr[2][k]);
                dp[i][j + 1][k + 1] = max(dp[i][j + 1][k + 1], dp[i][j][k] + 1ll * arr[1][j] * arr[2][k]);
                ans = max(ans, dp[i][j][k]);
            }
    printf("%lld\n", ans);
    return 0;
}