uva 1444 - Knowledge for the masses(高效)

题目链接:uva 1444 - Knowledge for the masses

题目大意:给出R和L,R表示有R行,L表示一行的最大长度。

对于每一行,给出n,然后是n个数,arr[i]为0表示空格,长度为1,否则表示书架,长度为arr[i]。现在人要从上边走到下边,问说最少移动几个书架,并且输出可以通过的路径坐标。

解题思路:c[i]表示第i个坐标有多少行可以通过,当c[i]==R时,表示人可以从该位置穿过整个书架。g[i]表示从i这个位置穿过的代价。然后对于每一行处理,pos[i]记录第i个空格的位置,vis[i]记录左移的代价,用来和右移代价作比较,取最小值。注意第二行输出的时候每个数后面都要根空格,否则PE。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int maxn = 1e6+5;
const int INF = 0x3f3f3f3f;

int R, L, c[maxn], g[maxn];
int n, arr[maxn], pos[maxn], vis[maxn];

void  input () {
    scanf("%d", &n);
    memset(vis, -1, sizeof(vis));

    int cnt = 0, mv = 0;
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
        if (arr[i] == 0) {
            mv++;
            pos[cnt++] = i;
            c[mv-1]++;
        } else {
            int k = min(cnt, arr[i]);
            mv = mv + arr[i];
            for (int j = 1; j <= k; j++) {
                int u = mv - j;
                vis[u] = i - pos[cnt-j] - j + 1;
                g[u] += vis[u];
                c[u]++;
            }
        }
    }

    reverse(arr, arr+n);

    cnt = 0;
    for (int i = 0; i < n; i++) {
        if (arr[i] == 0) {
            mv--;
            pos[cnt++] = i;
        } else {
            int k = min(cnt, arr[i]);
            mv = mv - arr[i];
            for (int j = 0; j < k; j++) {
                int u = mv + j;
                if (vis[u] == -1) {
                    vis[u] = i - pos[cnt-j-1] - j;
                    g[u] += vis[u];
                    c[u]++;
                } else {
                    int tmp = i - pos[cnt-j-1] - j;
                    g[u] += min(0, tmp - vis[u]);
                }
            }
        }
    }
}

void init () {
    scanf("%d%d", &R, &L);
    memset(c, 0, sizeof(c));
    memset(g, 0, sizeof(g));

    for (int i = 0; i < R; i++)
        input();
}

void solve () {
    int ans = INF, cnt = 0;
    for (int i = 0; i < L; i++) {
        if (c[i] == R) {
            if (g[i] < ans) {
                cnt = 0;
                ans = g[i];
            }

            if (g[i] == ans)
                vis[cnt++] = i;
        }
    }

    /*
    printf("%d\n%d", ans, vis[0]);
    for (int i = 1; i < cnt; i++)
        printf(" %d", vis[i]);
    printf("\n");
    */
    printf("%d\n", ans);
    for (int i = 0; i < cnt; i++)
        printf("%d ", vis[i]);
    printf("\n");
}

int main () {
    int cas;
    scanf("%d", &cas);
    while (cas--) {
        init();
        solve();
    }
    return 0;
}
时间: 2024-10-09 23:09:36

uva 1444 - Knowledge for the masses(高效)的相关文章

UVA 1444 - Knowledge for the masses

UVA 1444 - Knowledge for the masses 题目链接 题意:给定R排书架,现在要求最小代价移动书架打开一条通道,每次移动书架的代价为1(距离不限),问最小代价和最小代价的位置 思路:对于每一行,从左往右再从右往左各推一遍,每次把各个位置代价的最小值算出来,计算的过程要记录每个位置对应前面空位个数和空位位置,这样每个书架要移动的代价就能快速算出,最后处理往后,在每个位置遍历找出最小值位置即可 代码: #include <cstdio> #include <cst

UVALive - 4629 Knowledge for the masses 高效

题目大意:有一个人要找管理员,但前进的路上有很多的障碍 移动一个障碍到相应行的空位置需要花费1点体力,距离不限 问花费的最少体力值是多少,能前进的路是哪几条 解题思路:参考了学长的代码 求出每条前进道路的需要花费的最小体力值,再进行比较就可以 难点刚好就是这个了 vis[i]代表将该行的i列位置扫清需要消耗的体力值,flag[i]表示可以将第i列的几个位置扫清,如果i == R,就表示该列可以前行了,zero[i]表示该行第i个0所在的位置,cost[i]表示清每行第i列障碍的体力和 #incl

B - Knowledge for the masses

uva 1444 Description You are in a library equipped with bookracks that move on rails. There are many parallel rails, i.e., the bookracks are organized in several rows, see figure: The boockracks in the library. There is no passage to the librarian at

UVA - 11078 - Open Credit System (高效算法的应用!!)

UVA - 11078 Open Credit System Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu Submit Status Description Problem E Open Credit System Input: Standard Input Output: Standard Output In an open credit system, the students can choos

UVa 1210 (高效算法设计) Sum of Consecutive Prime Numbers

题意: 给出n,求把n写成若干个连续素数之和的方案数. 分析: 这道题非常类似大白书P48的例21,上面详细讲了如何从一个O(n3)的算法优化到O(n2)再到O(nlogn),最后到O(n)的神一般的优化. 首先筛出10000以内的素数,放到一个数组中,然后求出素数的前缀和B.这样第i个素数一直累加到第j个素数,就可表示为Bj - Bi-1 枚举连续子序列的右端点j,我们要找到Bj - Bi-1 = n,也就是找到Bi-1 = Bj - n. 因为Bj是递增的,所以Bi-1也是递增的,所以我们就

(高效算法设计)之高维问题 废料堆 Garbage heap Uva 10755

#include <iostream> #include <algorithm> #define FOR(i,s,p) for(int i=(s);i<=(p);i++) using namespace std; void expand(char i, bool b[]){ b[0] = i & 1; i >>= 1; b[1] = i & 1; i >>= 1; b[2] = i & 1; } // 这里使用了二项式中的思想,

UVA - 11462 - Age Sort (高效算法!!)

11462 Age Sort You are given the ages (in years) of all people of a country with at least 1 year of age. You know that no individual in that country lives for 100 or more years. Now, you are given a very simple task of sorting all the ages in ascendi

HashMap实现 Hash优化与高效散列

OverView Hash table based implementation of the Map interface. This implementation provides all of the optional map operations, and permits null values and the null key. (The HashMap class is roughly equivalent to Hashtable, except that it is unsynch

UVA 322 ships (POJ 1138)

题目地址: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=258 http://poj.org/problem?id=1138 题目描写叙述:  Ships  Probably everyone who ever attended school knows the game where two opposing players place