3.25-3.31

lzywakaka發表於2024-03-31

天梯賽2:

7-12 這是二叉搜尋樹嗎?

在滿足題意的前提下從前後分別往中間走模擬二叉樹的建立即可。

3.25-3.31
// /l、
//(゚、 。 7
// l、 ~ヽ
// じしf_, )ノ
//  不要放棄!貓貓會為你加油!
#include <bits/stdc++.h>
#define endl '\n'
#define int long long

using namespace std;

const int N = 2e5+10 , M = 1e6+10 ;

int k[N];
int n,st=0;
vector<int> ans;

void build(int l,int r) {
    if(l>r) return ;
    int i = l+1 , j=r;
    if(st) {
        while(i<=r && k[i]>=k[l]) i++;
        while(j>l && k[j]<k[l]) j--;
        i-- , j++;
    }
    else {
        while(i<=r && k[i]<k[l]) i++;
        while(j>l && k[j]>=k[l]) j--;
        i-- , j++;
    }
    if(j-i!=1) return ;
    build(l+1,i);
    build(j,r);
    ans.push_back(k[l]);
}

void solve() {
    cin >> n;
    for(int i=1;i<=n;i++) cin >> k[i];
    build(1,n);
    if(ans.size()==n) {
        cout << "YES" << endl;
        for(int i=1;i<=n;i++) cout << ans[i-1] << " \n"[i==n];
        return ;
    }
    ans.clear();
    st^=1;
    build(1,n);
    if(ans.size()==n) {
        cout << "YES" << endl;
        for(int i=1;i<=n;i++) cout << ans[i-1] << " \n"[i==n];
        return ;
    }
    cout << "NO" << endl;
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0) , cout.tie(0);
    int T = 1;
//    cin >> T ;
    while(T--) solve();
    return 0;
}
View Code

7-13 腫瘤診斷

三維bfs即可。(賽時寫的dfs爆棧空間導致re,好似了這下)

3.25-3.31
// /l、
//(゚、 。 7
// l、 ~ヽ
// じしf_, )ノ
//  不要放棄!貓貓會為你加油!
#include <bits/stdc++.h>
#define endl '\n'
#define int long long

using namespace std;

const int N = 2e5+10 , M = 1e6+10 ;

int n,m,l,t;
int k[70][1310][130];
bool vis[70][1310][130];

struct node {
    int l,x,y;
};

int dx[7]={0,1,-1,0,0,0,0};
int dy[7]={0,0,0,1,-1,0,0};
int dz[7]={0,0,0,0,0,1,-1};

int bfs(int a,int b,int c) {
    int cnt=1;
    queue<node> q;
    q.push({a,b,c});
    vis[a][b][c]=1;
    while(q.size()) {
        auto [z,x,y] = q.front();
        q.pop();
        for(int i=1;i<=6;i++) {
            int xt = dx[i]+x , yt = dy[i]+y , zt = dz[i]+z;
            if(xt>=1 && xt<=n && yt>=1 && yt<=m && zt>=1 && zt<=l && !vis[zt][xt][yt] && k[zt][xt][yt]==1) {
                cnt++;
                vis[zt][xt][yt]=1;
                q.push({zt,xt,yt});
            }
        }
    }
    return cnt;
}

void solve() {
    cin >> n >> m >> l >> t;
    for(int x=1;x<=l;x++) {
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=m;j++) cin >> k[x][i][j];
        }
    }
    int ans=0;
    for(int x=1;x<=l;x++) {
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=m;j++) {
                if(k[x][i][j]==1 && !vis[x][i][j]) {
                    int cnt = bfs(x,i,j);
                    if(cnt>=t) ans+=cnt;
                    cnt=0;
                }
            }
        }
    }
    cout << ans << endl;
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0) , cout.tie(0);
    int T = 1;
//    cin >> T ;
    while(T--) solve();
    return 0;
}
View Code

7-15 特殊堆疊

multiset(自定義排序)維護對頂堆。也可以權值樹狀陣列加二分。
這裡用的二分維護vector的增加和刪除操作。
3.25-3.31
// /l、
//(゚、 。 7
// l、 ~ヽ
// じしf_, )ノ
//  不要放棄!貓貓會為你加油!
#include <bits/stdc++.h>
#define endl '\n'
#define int long long

using namespace std;

const int N = 2e5+10 , M = 1e6+10 ;

int k[N];

void solve() {
    int n;
    cin >> n;
    int idx=0;
    vector<int> ans;
    while(n--) {
        string s;
        cin >> s;
        if(s=="Pop") {
            if(idx==0) {
                cout << "Invalid" << endl;
            }
            else {
                int x = k[idx--];
                ans.erase(lower_bound(ans.begin() , ans.end() , x));
                cout << x << endl;
            }
        }
        else if(s=="PeekMedian") {
            if(idx==0) {
                cout << "Invalid" << endl;
            }
            else {
                int x = (idx+1)/2-1;
                cout << ans[x] << endl;
            }
        }
        else {
            int x;
            cin >> x;
            k[++idx]=x;
            ans.insert(lower_bound(ans.begin() , ans.end() , x) , x);
        }
    }
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0) , cout.tie(0);
    int T = 1;
//    cin >> T ;
    while(T--) solve();
    return 0;
}
View Code

div4:

D:完全揹包板子改一下

3.25-3.31
// /l、
//(゚、 。 7
// l、 ~ヽ
// じしf_, )ノ
//  不要放棄!貓貓會為你加油!
#include <bits/stdc++.h>
#define endl '\n'
#define int long long

using namespace std;

const int N = 2e5+10 , M = 1e6+10 ;

int f[N];

vector<int> v;

void init() {
    for(int i=0;i<(1<<5);i++) {
        int x=0;
        for(int j=4;j>=0;j--) {
            if((i>>j)&1) x = x*10+1;
            else x=x*10;
        }
        f[x]=1;
        if(x) v.push_back(x);
    }
    f[100000]=1;
    for(auto & t : v) {
        for(int j=t;j<=100000;j++) {
            if(j%t==0) {
                int w = j/t;
                if(f[w]) f[j]=1;
            }
        }
    }
}

void solve() {
    int n;
    cin >> n;
    cout << (f[n] ? "YES" : "NO") << endl;
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0) , cout.tie(0);
    int T = 1;
    init();
    cin >> T ;
    while(T--) solve();
    return 0;
}
View Code

E:列舉字串長度檢查即可

3.25-3.31
// /l、
//(゚、 。 7
// l、 ~ヽ
// じしf_, )ノ
//  不要放棄!貓貓會為你加油!
#include <bits/stdc++.h>
#define endl '\n'
#define int long long

using namespace std;

const int N = 2e5+10 , M = 1e6+10 ;

void solve() {
    int n;
    cin >> n;
    string s;
    cin >> s;
    s = ' ' + s;
    for(int k=n;k>=1;k--) {
        if(n%k) continue;
        int cnt=0 , len=n/k;
        for(int i=1,j=1;i<=n;i++) {
            if(s[j]!=s[i]) cnt++;
            if(j==len) j=1;
            else j++;
        }
        string d = s + ' ';
        reverse(d.begin() , d.end());
        int res=0;
        for(int i=1,j=1;i<=n;i++) {
            if(d[j]!=d[i]) res++;
            if(j==len) j=1;
            else j++;
        }
        if(cnt<2 || res<2) {
            cout << len << endl;
            return ;
        }
    }
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0) , cout.tie(0);
    int T = 1;
    cin >> T ;
    while(T--) solve();
    return 0;
}
View Code

F:兩種寫法:

一:分類討論,並且必須滿足a+1 == c。

二:bfs維護層數,先a在b最後c,這種更好寫。

3.25-3.31
// /l、
//(゚、 。 7
// l、 ~ヽ
// じしf_, )ノ
//  不要放棄!貓貓會為你加油!
#include <bits/stdc++.h>
#define endl '\n'
#define int long long

using namespace std;

const int N = 2e5+10 , M = 1e6+10 ;

void solve() {
    int a,b,c;
    cin >> a >> b >> c;
    if(!a && !b) {
        if(c==1) cout << 0 << endl;
        else cout << -1 << endl;
    }
    else if(!a && !c) cout << -1 << endl;
    else if(!b && !c) cout << -1 << endl;
    else if(!c) cout << -1 << endl;
    else if(!a) {
        if(c==1) cout << b << endl;
        else cout << -1 << endl;
    }
    else if(!b) {
        if(a+1!=c) cout << -1 << endl;
        else {
            int cnt=0;
            for(int i=0;;i++) {
                int x = (1<<i);
                if(cnt+x>=a) {
                    cout << i+1 << endl;
                    return ;
                }
                else cnt+=x;
            }
        }
    }
    else {
        if(a+1!=c) {
            cout << -1 << endl;
            return ;
        }
        int ans=0;
        int cnt=0 , w;
        for(int i=0;;i++) {
            int x = (1<<i);
            if(cnt+x>a) {
                ans=i;
                a-=cnt;
                w=x;
                break;
            }
            else cnt+=x;
        }
        if(a+b<=w) {
            cout << ans+1 << endl;
            return ;
        }
        b-=w-a;
        int d = (w-a)+a*2;
        int res=b/d;
        if(b%d) res++;
        cout << ans+res+1 << endl;
    }
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0) , cout.tie(0);
    int T = 1;
    cin >> T ;
    while(T--) solve();
    return 0;
}
View Code

G:很經典的狀壓DP

初始化每個點作為起點的情況。

然後二進位制列舉每一種狀態,若當前狀態被標記,記錄一下答案,更新當前狀態可以到達的其他的狀態。

比如當前狀態f[i][j],現在列舉到一個點k,若j可以到k並且k這個點當前狀態沒有標記k點,就考慮更新k點。

3.25-3.31
// /l、
//(゚、 。 7
// l、 ~ヽ
// じしf_, )ノ
//  不要放棄!貓貓會為你加油!
#include <bits/stdc++.h>
#define endl '\n'
#define int long long

using namespace std;

const int N = 2e5+10 , M = 1e6+10 ;

void solve() {
    int n;
    cin >> n;
    vector<pair<string , string>> s(n+10);
    vector<vector<int>> d(n+10,vector<int>(n+10));
    for(int i=0;i<n;i++) cin >> s[i].first >> s[i].second;
    for(int i=0;i<n;i++) {
        for(int j=0;j<n;j++) {
            if(i==j) continue;
            if(s[i].first==s[j].first || s[i].second==s[j].second) d[i][j]=d[j][i]=1;
        }
    }
    vector<vector<int>> f((1<<n)+10,vector<int>(n+10));
    for(int i=0;i<n;i++) f[1<<i][i]=1;
    int ans=0;
    for(int i=1;i<(1<<n);i++) {
        for(int j=0;j<n;j++) {
            if(f[i][j]) {
                int res=0;
                for(int k=0;k<n;k++) {
                    if((i>>k)&1) res++;
                }
                ans=max(ans,res);
                for(int k=0;k<n;k++) {
                    if(((i>>k)&1)==0 && d[j][k]) {
                        f[i|(1<<k)][k]=1;
                    }
                }
            }
        }
    }
    cout << n-ans << endl;
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0) , cout.tie(0);
    int T = 1;
    cin >> T ;
    while(T--) solve();
    return 0;
}
View Code

天梯賽3:

7-14 天梯地圖

Dijkstra維護兩個鍵值即可。

3.25-3.31
// /l、
//(゚、 。 7
// l、 ~ヽ
// じしf_, )ノ
//  不要放棄!貓貓會為你加油!
#include <bits/stdc++.h>
#define endl '\n'

using namespace std;

const int N = 510 , M = 1e6+10 ;

struct node {
    int x,y,z;
    bool operator < (const node & a) const {
        return x > a.x;
    }
};

int n,m,st,en;
int fl[N],ft[N];
int disl[N],dist[N];
int L[N],T[N];
bool visl[N],vist[N];
vector<int> ansl,anst;
vector<node> vl[N],vt[N];

void bfsl(int x) {
    priority_queue<node> q;
    memset(disl , 0x3f , sizeof disl);
    memset(T , 0x3f , sizeof T);
    q.push({0,0,x});
    disl[x]=0 , T[x]=0;
    while(q.size()) {
        int t = q.top().z;
        q.pop();
        if(visl[t]) continue;
        visl[t]=1;
        for(auto & [u,w,d] : vl[t]) {
            if(disl[u] > disl[t] + w) {
                disl[u] = disl[t] + w;
                T[u]=T[t]+1;
                fl[u]=t;
                q.push({disl[u],T[u],u});
            }
            else if(disl[u] == disl[t] + w) {
                if(T[u]>T[t]+1) {
                    T[u] = T[t]+1 , fl[u]=t;
                    q.push({disl[u],T[u],u});
                }
            }
        }
    }
}

void bfst(int x) {
    priority_queue<node> q;
    memset(dist , 0x3f , sizeof dist);
    memset(L , 0x3f , sizeof L);
    q.push({0,0,x});
    dist[x]=0 , L[x]=0;
    while(q.size()) {
        int t = q.top().z;
        q.pop();
        if(vist[t]) continue;
        vist[t]=1;
        for(auto & [u,w,d] : vt[t]) {
            if(dist[u] > dist[t] + w) {
                dist[u] = dist[t] + w;
                L[u]=L[t]+d;
                ft[u]=t;
                q.push({dist[u],L[u],u});
            }
            else if(dist[u] == dist[t] + w) {
                if(L[u]>L[t]+d) {
                    L[u] = L[t]+d , ft[u]=t;
                    q.push({dist[u],L[u],u});
                }
            }
        }
    }
}

void solve() {
    cin >> n>> m;
    for(int i=1;i<=m;i++) {
        int v1,v2,way,l,t;
        cin >> v1 >> v2 >> way >> l >> t;
        vl[v1].push_back({v2,l,t});
        vt[v1].push_back({v2,t,l});
        if(way==0) {
            vl[v2].push_back({v1,l,t});
            vt[v2].push_back({v1,t,l});
        }
    }
    cin >> st >> en;
    fl[st]=-1 , ft[st]=-1;
    bfsl(st);
    bfst(st);

    int d = en;
    while(fl[d]!=-1) ansl.push_back(d) , d = fl[d];
    ansl.push_back(st);

    d = en;
    while(ft[d]!=-1) anst.push_back(d) , d = ft[d];
    anst.push_back(st);

    reverse(ansl.begin() , ansl.end());
    reverse(anst.begin() , anst.end());

//    cout << "ansl: " << endl;
//    for(auto & t : ansl) cout << t << ' ';
//    cout << endl;
//
//    cout << "anst: " << endl;
//    for(auto & t : anst) cout << t << ' ';
//    cout << endl;
//
//    cout << "dist: " << endl;
//    for(int i=0;i<n;i++) cout << dist[i] << " \n"[i==n-1];

    if(ansl==anst) {
        cout << "Time = " << dist[en] << "; Distance = " << disl[en] << ": ";
        for(int i=0;i<ansl.size();i++) {
            cout << ansl[i];
            if(i==ansl.size()-1) cout << endl;
            else cout << " => ";
        }
    }
    else {
        cout << "Time = " << dist[en] << ": ";
        for(int i=0;i<anst.size();i++) {
            cout << anst[i];
            if(i==anst.size()-1) cout << endl;
            else cout << " => ";
        }
        cout << "Distance = " << disl[en] << ": ";
        for(int i=0;i<ansl.size();i++) {
            cout << ansl[i];
            if(i==ansl.size()-1) cout << endl;
            else cout << " => ";
        }
    }
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0) , cout.tie(0);
    int T = 1;
//    cin >> T ;
    while(T--) solve();
    return 0;
}
View Code

相關文章