【牛客練習賽59】 A【DP】B【思維】C【三分】D【記憶化搜索】

文章目錄

A

思路:很經典的題目了,不僅可以判定是否有這樣的子序列,同時還可以找到有多少這樣的子序列。
Code:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

const int N = 1e5 + 11;
const int M = 1e6 + 11;
const int MOD = 1e9 + 7;

int XiaoQiao[20], Xiaohuihui[32];

int cnt[N];
char s1[] = "XiaoQiao";
char s2[ ] = "XiaoHuiHui";

bool deal(char *ss, string s){
    memset(cnt, 0, sizeof(cnt));
    int len = strlen(ss);
    cnt[len ] = 1;
    for(int i = s.size() - 1; i >= 0; i--){
        for(int j = 0; ss[j]; j++) {
            if(s[i] == ss[j]) {
                if(cnt[j + 1] > 0)
                    cnt[j] = 1;
            }
        }
    }
    return cnt[0] > 0;
}

int main(int argc, char **args){
    string s; cin >>s;
    if(deal(s1, s) && deal(s2, s)) puts("Happy");
    else puts("emm");
return 0;
}

B

思路:將題目中給的公式,進行化簡就行了。
Code:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

const int N = 1e5 + 11;
const int M = 1e6 + 11;
const int MOD = 1e9 + 7;

ll c[N];
int main(int argc, char **args){
    int n; scanf("%d", &n);
    for(int i = 0; i < n; i++){
        int a,b; scanf("%d%d", &a, &b);
        c[i] = b * 1ll * (a - b) * (a - b);
    }
    sort(c, c + n);
    ll ans = 0;
    for(int i = 1; i < n; i++){
        ans += c[i] - c[i - 1];
    }
    printf("%lld\n", ans);
return 0;
}

C

思路:一共就兩種合成裝備的方式,所以我們枚舉其中一個方式的次數,同時從直覺上看,如果全是某一種方式,結果不一定最優,應該是在某個中間,兩種組合取得平衡,組合裝備數量最多。所以問題轉化爲了,一個有極小值的問題,這種問題可以用三分解決。
Code:

#include <bits/stdc++.h>
using namespace std;
  
typedef long long ll;
typedef pair<int, int> pii;
  
const int N = 1e5 + 11;
const int M = 1e6 + 11;
const int MOD = 1e9 + 7;
  
ll x, y;
ll get(ll n){
    return min((x - 4 * n  ) / 2, (y - n ) / 3);
}
 
ll f(ll mid){
    if(4 * mid > x || mid > y) return 0;
    return mid + get(mid);
}
 
int main(int argc, char **args){
    int t; scanf("%d", &t);
    while(t--){
        scanf("%lld%lld", &x, &y);
         
        ll L, R, mid, midr;
        L = 0, R = min(x / 4, y);
        while(L + 2 < R){
            mid = (L + R) / 2;
            midr = (mid + R) / 2;
            if(f(mid) > f(midr)) R = midr;
            else L = mid;
        }
        mid = (L + R ) / 2;
        printf("%lld\n", max(max(f(L), f(R)), f(mid)));
    }
return 0;
}

D

思路:直接記憶化搜索。
Code:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

const int N = 1e5 + 11;
const int M = 1e6 + 11;
const int MOD = 1e9 + 7;

map<ll, int> mp;  // 因爲值大,所以用了map來記憶歷史值

int solve(ll n){
   if(mp[n]) return mp[n];
    if(2==solve(n / 2) || 2==solve(n - n / 2)) mp[n] = 1;
    else mp[n] = 2;
    return mp[n];  
} 
int main(int argc, char **args){
    int t; scanf("%d", &t);
    while(t--){  
        mp.clear();
        mp[1] = 2;
        mp[2] = 1;
        mp[3] = 1;
        mp[4] = 2;
        ll n; scanf("%lld", &n);
        puts((solve(n) == 1)? "XiaoHuiHui" :"XiaoQiao");
    }
return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章