zoukankan      html  css  js  c++  java
  • [BZOJ1697][Usaco2007 Feb]Cow Sorting牛排序

    1697: [Usaco2007 Feb]Cow Sorting牛排序

    Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 712  Solved: 416 [Submit][Status][Discuss]

    Description

    农夫JOHN准备把他的 N(1 <= N <= 10,000)头牛排队以便于行动。因为脾气大的牛有可能会捣乱,JOHN想把牛按脾气的大小排序。每一头牛的脾气都是一个在1到100,000之间的整数并且没有两头牛的脾气值相同。在排序过程中,JOHN 可以交换任意两头牛的位置。因为脾气大的牛不好移动,JOHN需要X+Y秒来交换脾气值为X和Y的两头牛。 请帮JOHN计算把所有牛排好序的最短时间。

    Input

    第1行: 一个数, N。

    第2~N+1行: 每行一个数,第i+1行是第i头牛的脾气值。

    Output

    第1行: 一个数,把所有牛排好序的最短时间。

    Sample Input

    3
    2
    3
    1

    输入解释:

    队列里有三头牛,脾气分别为 2,3, 1。

    Sample Output

    7

    输出解释:
    2 3 1 : 初始序列
    2 1 3 : 交换脾气为3和1的牛(时间=1+3=4).
    1 2 3 : 交换脾气为1和2的牛(时间=2+1=3).
     
    排个序找出每头牛应该排到的位置,然后可以发现交换的牛一定是属于同一个置换循环里,那么对于每个循环单独考虑
    有两种方法搞
    第一是每个元素和最小的一直换
    第二种是把外面的最小的换进来再不停换,最后换回来
    两种取个最小值就行了
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std; 
    char buf[10000000], *ptr = buf - 1;
    inline int readint(){
        int n = 0;
        char ch = *++ptr;
        while(ch < '0' || ch > '9') ch = *++ptr;
        while(ch <= '9' && ch >= '0'){
            n = (n << 1) + (n << 3) + ch - '0';
            ch = *++ptr; 
        }
        return n;
    }
    typedef long long ll;
    const int maxn = 10000 + 10;
    int num[maxn], pos[maxn], a[maxn];
    bool vis[maxn] = {false};
    int main(){
        fread(buf, sizeof(char), sizeof(buf), stdin);
        int N = readint();
        for(int i = 1; i <= N; i++) num[i] = a[i] = readint();
        sort(a + 1, a + N + 1);
        for(int i = 1; i <= N; i++) pos[i] = lower_bound(a + 1, a + N + 1, num[i]) - a;
        ll ans = 0;
        for(int j, Min, tot, siz, i = 1; i <= N; i++){
            if(vis[i]) continue;
            Min = tot = num[i];
            siz = 1;
            vis[i] = true;
            j = pos[i];
            while(!vis[j]){
                Min = min(Min, num[j]);
                tot += num[j];
                siz++;
                vis[j] = true;
                j = pos[j];
            }
            ans += min((ll)Min * (siz - 2), (ll)a[1] * (siz + 1) + Min) + tot;
        }
        printf("%lld
    ", ans);
        return 0;
    }
  • 相关阅读:
    响应式css样式
    组件 computed 与 vuex 中 getters 的使用,及 mapGetters 的使用,对象上追加属性,合并对象
    nginx 错误集锦
    动态的添加路由
    NProgress的使用 及 路由 token 定向的使用
    token的解码及 判断值不为空的方法
    nginx 的使用
    IT公司100题-tencent-打印所有高度为2的路径
    测试
    Objective-C 与 C++ 的异同
  • 原文地址:https://www.cnblogs.com/ruoruoruo/p/7553259.html
Copyright © 2011-2022 走看看