1. 程式人生 > >2019年牛客寒假算法基礎集訓營1

2019年牛客寒假算法基礎集訓營1

std 展示 背包 策略 暴力 只需要 基礎 輸出 [1]

2019年牛客寒假算法基礎集訓營1

A-模擬

倒序模擬
https://ac.nowcoder.com/acm/contest/317/A

代碼:

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

typedef long long ll;
int n;
ll X;
ll ans = 0;

struct ve{
    int opt;
    ll x;
};

struct ve V[110];

int main(){
    scanf("%d%ld",&n,&X);
    ans = (ll)X;
    for(int i=n;i>=1;i--){
        int opt;
        ll x;
        scanf("%d%ld",&opt,&x);
        V[i].opt = opt;
        V[i].x = x;
    }
    for(int i=1;i<=n;i++){
        if(V[i].opt == 1) ans -= V[i].x;
        if(V[i].opt == 2) ans += V[i].x;
        if(V[i].opt == 3) ans /= V[i].x;
        if(V[i].opt == 4) ans *= V[i].x;
    }
    printf("%lld",ans);
    return 0;
}

B貪心+構造(一大一小)

https://ac.nowcoder.com/acm/contest/317/B

1.輸入的序列其實用處不大,因為最終不需要輸出方案,我們只需要記錄下2/0/4分別出現的次數即可
一個顯然的構造策略是首先放置4, 0, 4, 0,直到其中一個用光。
接下來如果4多余,那麽可以按4,0,4,0,…,4,2,4,2,…(先4後2)的方法構造
如果0多余,可以按照4,0,4,0 … 4,0,2,0,2 …(先2後0)的方法構造
std中的a數組展示了其中一種最優的構造方案

2.實際上此題還可以推廣到更一般的情況,也就是第一個位置放最大的,第二個位置放最小的,第三個位置放
第二大的以此類推,這種思路寫起來也會更簡單一些

int a[N];
int main(){
    int n;
    LL sum=0;
 
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    
    sort(a,a+n+1);
 
    for(int i=n;i>n/2;i--)
        sum+=pow(a[i]-a[n-i],2)+pow(a[n-i+1]-a[i],2); //一大一小
 
    cout<<sum<<endl;
 
    return 0;
}

C-背包dp、線性基

#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e3+5;
int A[maxn];
int B[maxn];
int P[maxn];
int cnt;
void solve() {
    for (int i = 1; i <= cnt; ++i) {
        for (int j = 15; j >= 0; --j) {
            if ((A[i]>>j) & 1) {
                if (P[j] == 0) {
                    P[j] = A[i];
                    break;
                } else {
                    A[i] ^= P[j];
                }
            }
        }
    }
}
int main() {
    std::ios::sync_with_stdio(false);
    int n;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> B[i];
    }
    
    for (int i = 2; i < n; ++i) {
        if (B[i] < B[1] && B[i] > B[n]) {
            A[++cnt] = B[i];
        }
    }
    solve();
    int ans = B[1]^B[n];
    for (int j = 15; j >= 0; --j) {
        ans = max(ans, ans^P[j]);
    }
    if (ans > 0 && B[1] > B[n])
        cout << ans << endl;
    else
        cout << -1 << endl;
    return 0;
}

藍橋杯刷習慣了就只會暴搜了。。
dfs暴力搜索 過10%數據

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

typedef long long ll;

int n;
int a[3010];
int vst[3010];
ll ans = -1;
int flag = 0;

void dfs(int cur,int last,ll t){
    if(cur == n-1){
        if(a[last] > a[cur] || last == n-1){
            ans = max(ans,t^a[last]);
            flag = 1;
        }
        return;
    }
    
    for(int i=0;i<n;i++){
        if(!vst[i]){
            if(a[last] <= a[i]) continue;
            vst[i] = 1;
            ll dd = t;
            t ^= a[i];
            dfs(i,cur,t);
            t = dd;
            vst[i] = 0;
        }
    }
} 


int main(){
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    ans = a[0];
    vst[0] = 1;
    dfs(0,0,ans); //0 0邊界需要調整 
//  printf("%lld",ans);
    if(flag || ans != a[0] || n==1|| ans ==0) printf("%lld",ans);
    else printf("-1");
    return 0;
}

2019年牛客寒假算法基礎集訓營1