zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    “不裁员”才是公司度过艰难时期的聪明选择
    oracle服务端与客户端字符集不同导致中文乱码解决方案
    [转]ABAP数据库操作系列(5)
    [转]ABAP数据库操作系列(2)
    [转]整理的函数
    [转]ABAP数据库操作系列(6)
    [转]ABAP数据库操作系列(7)
    [转]Authoritycheck
    [转]ABAP Program to Display SAP Icons
    [转]ABAP数据库操作系列(3)
  • 原文地址:https://www.cnblogs.com/fht-litost/p/7266399.html
Copyright © 2011-2022 走看看