BAPC 2014 Preliminary

题库链接戳这里

A. Choosing Ice Cream

给出n,k。即有n种冰淇淋,你有一个k面骰子,问最少摇几次骰子能公平地决定出选择。不可公平抉择出的话输出"unbounded"。
如果n=1,那么不必抉择,直接为0.
否则解应该是使得k^(i) mod n 成立的最小i。留意,K范围10^9,那么要用long long,否则溢出。因为n也是10^9内,所以解i,最多就是log2(n),即29,写30也可以,越出这个还没找到应该认为无解。

#include <bits/stdc++.h>
using namespace std;

#define ll long long
const int maxN = 1e5 + 5;
ll N, M, K, T;

int main() {
    scanf("%lld", &T);
    while (T--) {
        scanf("%lld %lld", &N, &K);

        if (N == 1) {
            puts("0");
            continue;
        }

        int ans = 0;
        int tk = K;
        K = 1;
        int cnt = 1;
        while (K != 0) {
            K = (K * tk) % N;
            ans += 1;
            if (cnt++ > 30) {
                puts("unbounded");
                break;
            }
        }
        if (cnt <= 30)
            printf("%d\n", ans);
    }
    return 0;
}
B. Failing Components

有一幅图,某些点坏了之后,经一定延迟(边权)会导致以他为基础的点的损坏。给出N,D,C,即点数,边数,初始坏点编号,问这个点会导致多少坏点(包括自己),以及所有点坏了之后,用时多少。

建立边的struct,记录终点和边权,再来一个dis,dis[i]表示源点蔓延至i点的最少耗时,初始化为inf。那么能蔓延到的必将非inf,可更新的时候更新为更小值,这个用bfs完成更新。最后非inf的个数和非inf的最大值即为解。

#include <bits/stdc++.h>
using namespace std;

#define ll long long
const int inf = 0x3f3f3f3f, maxN = 1e5 + 5;
int N, M, K, T, D, C;
int dis[maxN];

struct Edge {
    int to, cost;
    Edge(int a = 0, int b = 0, int c = 0) : 
        to(a), cost(b) {}
};

vector<Edge> E[maxN];

void bfs(int s) {
    queue<int> Q;
    memset(dis, inf, sizeof(dis));
    dis[s] = 0;
    Q.push(s);

    while (!Q.empty()) {
        int t = Q.front();
        Q.pop();
        for (int i = 0; i < E[t].size(); ++i) {
            int nxt = E[t][i].to;
            if (dis[nxt] > dis[t] + E[t][i].cost) {
                dis[nxt] = dis[t] + E[t][i].cost;
                Q.push(nxt);
            }
        }
    }
}

int main() {
    scanf("%d", &T);
    while (T--) {
        scanf("%d%d%d", &N, &D, &C);

        for (int i = 1; i <= N; ++i)
            E[i].clear();
        int u, v, w;
        for (int i = 0; i < D; ++i) {
            scanf("%d%d%d", &u, &v, &w);
            E[v].push_back(Edge(u, w));
        }

        bfs(C);
        int ans1 = 0, ans2 = 0;
        for (int i = 1; i <= N; ++i) {
            if (dis[i] != inf) {
                ++ans1;
                ans2 = max(ans2, dis[i]);
            }
        }
        printf("%d %d\n", ans1, ans2);
    }
    return 0;
}
D. Lift Problems

题意: 有一栋N层([1,N]层)高的楼,一开始有很多人,认为在第0层。电梯从0层收完人后开始往上统计愤怒值。先给出每一层楼欲停的人数。若还没到自己想到的楼层而提早电梯开门(停)了,这部分人愤怒值+1。若经过自己想停的楼层而没停,这部分人愤怒值+1,而且会在下一次停的时候,即在更高楼层出来,走楼梯回自己的目的地,可以认为消失。问:运完所有人,愤怒值最少可以是多少?

一开始想的贪心,其实有漏洞。原因在于:决策的时候,判断的根据是不完整的。我一开始想,假设在b1层有a1人要停,下一次停的地方是b2层,有a2人要下。那么在b1层,根据电梯停与不停,计算出两种愤怒值,取小的进行贪心决策。关键在于:下一次停的地方未知,所以思路错误。

正确方法是dp。令dp[i]为在i层停的时候的最小愤怒值。然后搜索所有直接到达i层的方式,在这所有方式中,找愤怒值最小的作为答案即可。最终答案是dp[N]。
进一步解析:第i层停的最小愤怒值,应该是比自己低的楼层j的最小愤怒值加上由于从j直接到i,这之间由于跳过一些楼层产生的 skipAnger,以及,比i层高的那些楼层因为在i层停而产生的愤怒值。

这里有个小地方可以留意:按理说j习惯从0到i-1扫过去,找dp最小值,但是每一层都要统计该层到i-1层的skipAnger,不如从i-1层往前遍历,skipAnger逐层递增,利用后缀和顺畅地去掉了一个for循环。

#include <bits/stdc++.h>
using namespace std;

#define ll long long
const int inf = 0x3f3f3f3f, maxN = 2e3 + 5;

int N, M, T;
ll S[maxN], dp[maxN];
// dpi 在第i层停留的最小愤怒值

int main() {
    scanf("%d", &T);
    while (T--) {
        scanf("%d", &N);

        ll sum = 0;
        for (int i = 1; i <= N; ++i) {
            scanf("%lld", &S[i]);
            sum += S[i];
        }

        dp[0] = 0;
        for (int i = 1; i <= N; ++i) {
            sum -= S[i];
            ll skipAnger = 0;
            dp[i] = inf;
            for (int j = i - 1; j >= 0; --j) {
                dp[i] = min(dp[i], dp[j] + skipAnger + sum);
                skipAnger += (i - j) * S[j];
            }
        }
        printf("%lld\n", dp[N]);
    }
    return 0;
}
F.Runway Planning

水题,给一个数字n,n/10后的小数四舍五入后取整。如果n=0,则改为取18,记得不足2位补零。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int N, T;

int main() {
    scanf("%d", &T);
    while (T--) {
        scanf("%d", &N);
        N += 5;
        N /= 10;
        N %= 18;
        if (N == 0)
            N = 18;
        printf("%02d\n", N);
    }
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341