Codeforces掉分记 round318(div2)

Codeforces掉分记 round318(div2)

又升回紫名了233,这一次就差一点点就AK了,还没有AK过。

(以下题目描述摘自codeforces)

A题 Bear and Elections

题目描述

Limak is a grizzly bear who desires power and adoration. He wants to win in upcoming elections and rule over the Bearland.

There are n candidates, including Limak. We know how many citizens are going to vote for each candidate. Now i-th candidate would get ai votes. Limak is candidate number 1. To win in elections, he must get strictly more votes than any other candidate.

Victory is more important than everything else so Limak decided to cheat. He will steal votes from his opponents by bribing some citizens. To bribe a citizen, Limak must give him or her one candy - citizens are bears and bears like candies. Limak doesn’t have many candies and wonders - how many citizens does he have to bribe?

Input

The first line contains single integer n (2?≤?n?≤?100) - number of candidates.

The second line contains n space-separated integers a1,?a2,?…,?an (1?≤?ai?≤?1000) - number of votes for each candidate. Limak is candidate number 1.

Note that after bribing number of votes for some candidate might be zero or might be greater than 1000.

Output

Print the minimum number of citizens Limak must bribe to have strictly more votes than any other candidate.

题意

有N个候选人,每人有ai张选票,这个人要把别人的支持者收买过来,问最小费用。

解法

A题自古都是大水题,把选票存入优先队列里,每次收买选票最多的,最多收买10^5个。想了半天优美解法,结果交上去名次500+…

#include<bits/stdc++.h>

using namespace std;

int N;
int A[1005];

priority_queue<int> pq;

int main(){
    scanf("%d",&N);
    int now;
    scanf("%d",&now);
    for(int i=2;i<=N;i++){
        scanf("%d",&A[i]);
        pq.push(A[i]);
    }
    int res = 0;
    while(true){
        int pqtop = pq.top();
        if(pqtop < now) break;
        pq.pop();
        pq.push(pqtop - 1);
        res ++;
        now ++;
    }
    printf("%d\n",res);
    return 0;
}

B题 Bear and Three Musketeers

题目描述

Do you know a story about the three musketeers? Anyway, you will learn about its origins now.

Richelimakieu is a cardinal in the city of Bearis. He is tired of dealing with crime by himself. He needs three brave warriors to help him to fight against bad guys.

There are n warriors. Richelimakieu wants to choose three of them to become musketeers but it’s not that easy. The most important condition is that musketeers must know each other to cooperate efficiently. And they shouldn’t be too well known because they could be betrayed by old friends. For each musketeer his recognition is the number of warriors he knows, excluding other two musketeers.

Help Richelimakieu! Find if it is possible to choose three musketeers knowing each other, and what is minimum possible sum of their recognitions.

Input

The first line contains two space-separated integers, n and m (3?≤?n?≤?4000, 0?≤?m?≤?4000) — respectively number of warriors and number of pairs of warriors knowing each other.

i-th of the following m lines contains two space-separated integers ai and bi (1?≤?ai,?bi?≤?n, ai?≠?bi). Warriors ai and bi know each other. Each pair of warriors will be listed at most once.

Output

If Richelimakieu can choose three musketeers, print the minimum possible sum of their recognitions. Otherwise, print “-1” (without the quotes).

题意

有N个勇士,他们有一个关系网络,从中选取三个人,使他们互相认识并且这三个人认识的人数总和最少(他们三个之间除外)。

解法

简单搜索题,深搜出相连的三个勇士,再计算认识人数,每个勇士认识人数可以预处理。

小优化:避免查重可以按序号增序搜索。

#include<bits/stdc++.h>

using namespace std;

int N,M;
const int SIZE = 4005;
int know[SIZE];

set<int> S[SIZE];

struct P{
    int next,to;
}p[2*SIZE];
int head[SIZE];
int no;

void init(){
    memset(head,-1,sizeof(head));
    no = 0;
}

void add(int a,int b){
    p[no].to = b;
    p[no].next = head[a];
    head[a] = no++;
}

bool used[SIZE];
int fir;
int mid;
int res = 0x7fffffff;

void dfs(int u,int d){
    if(d == 2) mid = u;
    if(d == 3){
        if(S[u].find(fir) != S[u].end()){
            int temp = know[fir] + know[mid] + know[u] - 6;
            if(temp < res) res = temp;
        }
        return;
    }
    used[u] = true;
    for(int i = head[u]; i != -1; i = p[i].next){
        int v = p[i].to;
        if(used[v] || v < u) continue;
        dfs(v,d+1);
    }
    used[u] = false;
}

int main(){
    init();
    scanf("%d %d",&N,&M);
    while(M--){
        int a, b;
        scanf("%d %d", &a, &b);
        know[a]++;
        know[b]++;
        add(a,b);
        add(b,a);
        S[a].insert(b);
        S[b].insert(a);
    }
    for(fir = 1; fir <= N; fir++) dfs(fir,1);
    if(res == 0x7fffffff) printf("-1\n");
    else printf("%d\n",res);
    return 0;
}

C题 Bear and Poker

题目描述

Limak is an old brown bear. He often plays poker with his friends. Today they went to a casino. There are n players (including Limak himself) and right now all of them have bids on the table. i-th of them has bid with size ai dollars.

Each player can double his bid any number of times and triple his bid any number of times. The casino has a great jackpot for making all bids equal. Is it possible that Limak and his friends will win a jackpot?

Input

First line of input contains an integer n (2?≤?n?≤?105), the number of players.

The second line contains n integer numbers a1,?a2,?…,?an (1?≤?ai?≤?109) — the bids of players.

Output

Print “Yes” (without the quotes) if players can make their bids become equal, or “No” otherwise.

题意

有N个数字,对每个数字可以进行两种操作(无限次):

1.将这个数乘2

2.将他乘3

问这N个数字是否可以变为相同的数字。

解法

显然这N个数字分别除掉他们的gcd对结果没有影响,假设可以变为相同的数字,设这个数字为P:

  • P = 2^i1 * 3^i2 * 5^i3 …
  • 显然,除了2和3以外,其他素因子的乘积一定是他们的gcd的因子

即每个数字除与他们的gcd后,他们的素因子只能有2和3.

#include<bits/stdc++.h>

using namespace std;

int N;
const int SIZE = 100005;
int A[SIZE];

int gcd( int a, int b )
{
    if( b == 0) return a;
    return gcd( b, a%b );
}

int gd;

bool sat(int n){
    while(!(n%2)) n /= 2;
    while(!(n%3)) n /= 3;
    if(n == 1) return true;
    return false;
}

bool solve(){
    for(int i = 1;i <= N; i++){
        if(!sat(A[i]/gd)) return false;
    }
    return true;
}

int main(){
    scanf("%d",&N);
    for(int i = 1; i <= N; i++){
        scanf("%d",&A[i]);
    }
    gd = A[1];
    for(int i = 2; i <= N; i++){
        gd = gcd(gd, A[i]);
    }
    if(solve()) puts("Yes");
    else puts("No");
    return 0;
}

D题 Bear and Blocks

题目描述

Limak is a little bear who loves to play. Today he is playing by destroying block towers. He built n towers in a row. The i-th tower is made of hi identical blocks. For clarification see picture for the first sample.

Limak will repeat the following operation till everything is destroyed.

Block is called internal if it has all four neighbors, i.e. it has each side (top, left, down and right) adjacent to other block or to the floor. Otherwise, block is boundary. In one operation Limak destroys all boundary blocks. His paws are very fast and he destroys all those blocks at the same time.

Limak is ready to start. You task is to count how many operations will it take him to destroy all towers.

Input

The first line contains single integer n (1?≤?n?≤?105).

The second line contains n space-separated integers h1,?h2,?…,?hn (1?≤?hi?≤?109) — sizes of towers.

Output

Print the number of operations needed to destroy all towers.

题意

给N列方块,每次删掉边缘的方块,问要进行多少次操作将所有方块删掉。

解法

对于第 i 列方块,设使其消去的最小操作次数为f[i],那么有

  • f[i] = min(h[i], f[i-1] + 1, f[i + 1] + 1)

由此递推关系得出:

  • f[i] = min(h[i],min(h[i-1]+1, f[i-2] + 2, f[i] + 2), min(h[i+1]+1, f[i+2]+2, f[i]+2))
  • = min(h[i],h[i-1]+1,f[i-2]+2,h[i+1]+1,f[i+2]+2)
  • = min(h[i],

    h[i-1]+1,…,h[i-j]+j,h[2]+N-1,f[1]+N,

    h[i+1]+1,…,h[i+k]+k,h[N-1]+N-1,f[N]+N)

  • f[1] = f[N] = 1

这样就可以从左到右、从右到左遍历两边数组,得到f[i],f[i]的最大值即是答案。

#include<bits/stdc++.h>

using namespace std;

int N;
const int SIZE = 100005;
int A[SIZE];
int res[SIZE];

int main(){
    scanf("%d",&N);
    for(int i=1;i<=N;i++){
        scanf("%d",&A[i]);
        res[i] = A[i];
    }
    int now = 0;
    for(int i=1;i<=N;i++){
        int temp = now + 1;
        now = res[i] = min(res[i],temp);
    }
    now = 0;
    for(int i=N;i>=1;i--){
        int temp = now + 1;
        now = res[i] = min(res[i],temp);
    }
    int ans = 0;
    for(int i=1;i<=N;i++)
        if(ans < res[i]) ans = res[i];
    printf("%d\n",ans);
    return 0;
}

E题 Bear and Drawing

题目描述

Limak is a little bear who learns to draw. People usually start with houses, fences and flowers but why would bears do it? Limak lives in the forest and he decides to draw a tree.

Recall that tree is a connected graph consisting of n vertices and n?-?1 edges.

Limak chose a tree with n vertices. He has infinite strip of paper with two parallel rows of dots. Little bear wants to assign vertices of a tree to some n distinct dots on a paper so that edges would intersect only at their endpoints — drawn tree must be planar. Below you can see one of correct drawings for the first sample test.

Is it possible for Limak to draw chosen tree?

Input

The first line contains single integer n (1?≤?n?≤?105).

Next n?-?1 lines contain description of a tree. i-th of them contains two space-separated integers ai and bi (1?≤?ai,?bi?≤?n,?ai?≠?bi) denoting an edge between vertices ai and bi. It’s guaranteed that given description forms a tree.

Output

Print “Yes” (without the quotes) if Limak can draw chosen tree. Otherwise, print “No” (without the quotes).

题意

给你无限长的两排点,问是否可以画出题目所给的树(不能有交叉).

解法

我先定义这几种树:

1. N-TREE :有N个单链的(儿子节点数等于这个子树的叶子节点数)

2. X-TREE:(随意命名的- -)就是叶子节点数大于儿子节点数的数

可以发现:以任意节点为根(设这个点为u),以u的子节点为根的子树最多只能有2个X-TREE、M-TREE(M>2),其余都必须为叶子、1-TREE、2-TREE。

这样就可以用搜索来解决,对于一个固定的有两个X-TREE、M-TREE(M>2)子节点的根,其余节点最多只能有一个(X-TREE、M-TREE(M>2))的子节点。

先用一边dfs找到这个点,如果没有,显然输出yes,找到后再进行一遍dfs看是否满足条件

(虽然是O(N)的算法,但是感觉还是有点挫,希望批评指正)

#include<bits/stdc++.h>

using namespace std;

int N;

const int SIZE = 100005;

struct P{
    int next,to;
}p[2*SIZE];
int head[SIZE];
int no;

void init(){
    memset(head,-1,sizeof(head));
    no = 0;
}

void add(int a,int b){
    p[no].to = b;
    p[no].next = head[a];
    head[a] = no++;
}

int used[SIZE];
bool haveans = true;
int st = -1;

int dfs(int u){
    used[u] = true;
    bool islef = true;
    int chd = 0;
    int cnt = 0;
    int sat = 0;
    for(int i=head[u];i!=-1;i=p[i].next){
        int v = p[i].to;
        if(used[v]) continue;
        islef = false;
        int temp = dfs(v);
        if(temp == 1) cnt++;
        if(temp <= 2) sat++;
        chd++;
    }
    if(islef) return 1;
    if(chd - sat > 2) haveans = false;
    else if(chd - sat > 1 && u != st) haveans = false;
    if(chd == cnt) return cnt;
    else return 10000;
}

bool used1[SIZE];

int dfs1(int u){
    used1[u] = true;
    bool islef = true;
    int chd = 0;
    int cnt = 0;
    int sat = 0;
    for(int i=head[u];i!=-1;i=p[i].next){
        int v = p[i].to;
        if(used1[v]) continue;
        islef = false;
        int temp = dfs1(v);
        if(temp == 1) cnt++;
        if(temp <= 2) sat++;
        chd++;
    }
    if(islef) return 1;
    if(chd - sat > 1) st = u;
    if(chd == cnt) return cnt;
    else return 10000;
}

int main(){
    scanf("%d",&N);
    init();
    for(int i = 1; i < N; i++){
        int a,b;
        scanf("%d%d",&a,&b);
        add(a,b);
        add(b,a);
    }

    dfs1(1);
    if(st < 0){
        puts("Yes\n");
        return 0;
    }
    //printf("st=%d\n",st);
    dfs(st);
    if(haveans) printf("Yes\n");
    else printf("No\n");
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-07-30 18:17:04

Codeforces掉分记 round318(div2)的相关文章

Codeforces Round #545 (Div. 2) 掉分记

每次CF后,我的rating下降,掉分让我悲痛欲绝 ——题记 ### 前言 这次 CF 时间可谓是极好的,17:05 开始,时长 2h 30min. 4:40 回到家,开电脑. 在看了一会书后,比赛开始了. ### 正文 首先,第一个掉分的 flag 出现了! 卡,卡,卡! CF 又双叒叕卡了! 1分钟过去了…… 2分钟过去了…… 3分钟过去了…… Dashboard 一直打不开.. 当时间已经接近 17:10 分的时候,我终于打开了 A 题.. 然而,这还并不是我掉分的所有原因. 先迅速浏览了

Codeforces Round 480 Div 2 光荣掉分记

痛 痛苦 痛苦啊. 越接近黄名想的越多了啊…… 都说了不要在意rating这破玩意了…… 没出E就算了,策略问题. 居然还FST了: FST个D就算了: FST个A算个**啊. 紧张的时候总会写出一些垃圾代码. 痛苦啊. 原文地址:https://www.cnblogs.com/cxhscst2/p/9017306.html

CODEFORCES掉RATING记 #4

比赛:Codeforces Round #427 (Div. 2) 时间:2017.7.31晚 开场发现有6道题,都是水题(可能我只会做水题) A:比较\(2t_1+sv_1\)与\(2t_2+sv_2\)的大小 B:给你一个数字串,要求所有数字的和\(\geq k\),问你最少要改多少个数字.从\(0\)到\(9\)枚举,每次把当前数字改成\(9\) C:给你\(n\)个星星,亮度呈周期性变化(周期相同且\(\leq11\)),每次问你一个矩形内的星星在时刻\(t\)的亮度和是多少.就出每个星

cf掉分记——Avito Code Challenge 2018

再次作死的打了一次cf的修仙比赛感觉有点迷.. 还好掉的分不多(原本就太低没法掉了QAQ) 把会做的前三道水题记录在这.. A: Antipalindrome emmmm...直接暴力枚举 code: //By Menteur_Hxy #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; int n,ans; cha

CODEFORCES掉RATING记 #3

比赛:Codeforces Round #426 (Div. 2) 时间:2017.7.30晚 开场先看AB A:给你两个方向,和旋转次数(每次旋转90度),问你旋转方向是什么 B:给你一个字符串,问你是否存在一个位置使得它前面后面都出现过的字母\(>\)k个 前两题比较简单 C:两个人在玩一个游戏.初始时两个人的分数都是\(1\).每次一个人的分数\(\times k\),另一个人的分数\(\times k^2\).给你\(n\)个结果问有没有可能出现这个结果. pollard rho暴力分解

Codeforces Round #535 (Div. 3)小上分记

Codeforces Round #535 (Div. 3)小上分记 前言 被拉去买新年衣服了,导致半小时后才进场. 虽然做了4道题,但是rating还是涨得不多. 用predictor看了rating变化后心灰意冷,不看E题了. A ...800的难度. B 本来还在想要不要用什么STL.后来发现直接用桶就行了.然后就可以水过了. C 题意差点理解不了. 就6种情况都去考虑一下,找最小代价的即可.不要考虑少了. 每次都是\(O(n)\)的,所以能搞. D 贪心地换字母即可. E 坑.待填. 原

【CF】掉分总结

比赛总结 前情提要 自从前段时间连续掉分,就心态崩了,还是自己太菜,一直想写个总结,看看这几场比赛都干了啥,以后准备怎么办.鸽了这么久的总结,是该写写了. 这是正文 首先大致提一下情感曲线(菜的真实): 那一晚,那一夜,sc大佬突然qq发消息给我,"打cf吗",我眉头一紧,这个cf莫非是穿越火线?又一想大佬才不会玩这种游戏,又一想,难道是codeforces?我颤颤巍巍的回了"codeforces?",大佬回的很快,扔给我了个链接,并说"这是616,你做吧

Codeforces Round 530 大下分记

Codeforces Round 530 赛前觉得还是要下分的.希望是毒奶. 没想到是大毒奶.rating -91 ->1329 我又绿了. 以后再也不熬夜打cf了,一点状态都没有. A 还是考英语.能不能一次过就看你能不能注意到雪球的质量可能变成负数. 我错了一次,然后重新读题才发现,最后才在9min改对. B 教训:不要看机翻!认真读英语! 我就是没有认真读题,才落得连B题都切不了的下场.rating可想而知 它的题意是有一个竖的线段,其他的同纵坐标的就都可以表示,有一个横的线段,其他的同横

CF下分记(

Educational Codeforces Round 80 [Rated for Div. 2] 开题,看A题 ... 这不是水题吗? 然后脑抽写了个神奇的东西,pp了,就没管精度什么的 看B题 啊这个有点恶心,写个暴力吧 写着写着不太对劲,又推了下式子,发现可以简单变形一下然后就出了,交上去, 也pp了 (其实已经一个小时过去了 看C题 诶呀有点恶心,推四十分钟式子推不出来,无奈又去看了一眼题目,发现看错题了,我艹你个百度翻译(bushi 又过了十分钟... 好像是个组合数啊 时间到了,凉