• GYM 101173 F.Free Figurines(贪心||并查集)


    原题链接

    题意
    俄罗斯套娃,给出一个初始状态和终止状态,问至少需要多少步操作才能实现状态转化

    贪心做法
    如果完全拆掉再重装,答案是p[i]和q[i]中不为0的值的个数。现在要求寻找最小步数,显然要减去一些多余的步数。如果初始的一些链的前端是终止的某一条链的连续的一部分,那么这条链就不用被拆开再连上,这样每一个长度为x的链对答案的贡献就是-2*(x-1),对每条链进行同样的操作之后就是答案

    #include <iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #define ll long long
    #define ull unsigned long long
    #define LOCAL
    
    using namespace std;
    const int maxn=1e5+10;
    const int inf=0x3f3f3f3f;
    const int mod=1e9+7;
    
    int p[maxn],q[maxn];
    int n;
    int main(){
        scanf("%d",&n);
        int vis[maxn];
        int ans=0;
        for(int i=1;i<=n;i++){
            scanf("%d",&p[i]);
            if(p[i]) vis[p[i]]=1,ans++;
        }
        for(int i=1;i<=n;i++){
            scanf("%d",&q[i]);
            if(q[i]) vis[q[i]]=1,ans++;
        }
        
        for(int i=1;i<=n;i++){
            if(!vis[i]){
                int x=i;
                while(p[x]&&q[x]&&p[x]==q[x]){
                    ans-=2;
                    x=p[x];
                }
            }
        }
        printf("%d
    ",ans);
        return 0;
    }

    并查集

    只能进行2个操作:
    1、 把一个没有父节点的节点作为一个 没有父节点和子节点的节点的子节点,代价为 1;

    2、把一个没有父节点的节点的子节点去掉,代价为1;

    那么只能对free的节点进行操作,所以当ai!=bi时,要先把ai拆掉,但必须先满足ai为free才能把i变成free,
    同理把i插到bi上时也要满足bi节点为free(即该节点没有父节点)。

    #include <iostream>
    #include <cstdio>
     
    using namespace std;
    typedef long long LL;
    const int MAXN = 1e5 + 8;
     
    int a[MAXN], b[MAXN], fa;
     
    int main()
    {
        #ifdef LOCAL
        freopen("f.txt", "r", stdin);
        //freopen("f.out", "w", stdout);
        int T = 4;
        while(T--){
        #endif // LOCAL
        ios::sync_with_stdio(false); cin.tie(0);
     
        int n, i, ans = 0, t;
        cin >> n;
        for(i = 1; i <= n; i++){
            cin >> a[i];
        }
        for(i = 1; i <= n; i++){
            cin >> b[i];
        }
        for(i = 1; i <= n; i++){
            if(a[i] == b[i]) continue;
            if(a[i] != 0){
                ans++;
                fa = a[i];
                a[i] = 0;
                while(a[fa]){
                    t = fa;
                    fa = a[fa];
                    a[t] = 0;
                    ans++;
                }
            }
        }
        for(i = 1; i <= n; i++){
            if(a[i] == b[i]) continue;
            if(b[i] != 0){
                fa = a[b[i]];
                if(fa){
                    a[b[i]] = 0;
                    ans++;
                }
                else{
                    continue;
                }
                while(a[fa]){
                    t = fa;
                    fa = a[fa];
                    a[t] = 0;
                    ans++;
                }
            }
        }
        for(i = 1; i <= n; i++){
            if(a[i] == b[i]) continue;
            ans++;
        }
        cout << ans << endl;
        return 0;
    }
  • 相关阅读:
    20192426 202120222 《网络与系统攻防技术》实验五实验报告
    人人站CMS更新V1.4.0版本,新增会员功能
    PMP4.8.11 风险登记册与风险报告
    PMP工具与技术4.8.11 识别风险技术假设条件分析\SWOT\提示清单
    PMP4.8.1 识别风险
    python监控文件变化
    Linux为所有用户安装Miniconda
    hash模式和history模式
    长轮询和短轮询
    BFC(块级格式化上下文)
  • 原文地址:https://www.cnblogs.com/fht-litost/p/7266399.html
Copyright © 2020-2023  润新知