GoldCoder(金狗杯——福师大周赛) Run #2 题解

比赛地址:
http://acm.fjnu.edu.cn/JudgeOnline/contest.php?cid=1004
还想交一发的话可以去problem set里头找

1055: 1-2-A
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 29 Solved: 13

Submit Status Web Board
Description
Alena has successfully passed the entrance exams to the university and is now looking forward to start studying.
One two-hour lesson at the Russian university is traditionally called a pair, it lasts for two academic hours (an academic hour is equal to 45 minutes).
The University works in such a way that every day it holds exactly n lessons. Depending on the schedule of a particular group of students, on a given day, some pairs may actually contain classes, but some may be empty (such pairs are called breaks).
The official website of the university has already published the schedule for tomorrow for Alena’s group. Thus, for each of the n pairs she knows if there will be a class at that time or not.
Alena’s House is far from the university, so if there are breaks, she doesn’t always go home. Alena has time to go home only if the break consists of at least two free pairs in a row, otherwise she waits for the next pair at the university.
Of course, Alena does not want to be sleepy during pairs, so she will sleep as long as possible, and will only come to the first pair that is presented in her schedule. Similarly, if there are no more pairs, then Alena immediately goes home.
Alena appreciates the time spent at home, so she always goes home when it is possible, and returns to the university only at the beginning of the next pair. Help Alena determine for how many pairs she will stay at the university. Note that during some pairs Alena may be at the university waiting for the upcoming pair.
Input
The first line of the input contains a positive integer n (1 ≤ n ≤ 100) — the number of lessons at the university.
The second line contains n numbers ai (0 ≤ ai ≤ 1). Number ai equals 0, if Alena doesn’t have the i-th pairs, otherwise it is equal to 1. Numbers a1, a2, …, an are separated by spaces.
Output
Print a single number — the number of pairs during which Alena stays at the university.

Sample Input
5
0 1 0 1 1
7
1 0 1 0 0 1 0
1
0
Sample Output
4
4
0

题意:签到题,其实就是在说给你一个串每次遇到1或孤立的0比如:101酱紫 就加1 最后输出累加的结果

#include "iostream"
#include "cstring"
#include "cstdio"
#include "string.h"

using namespace std;

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int count=0;
        int start=1,end=n;
        int last;
        int a[1000];
        //从分别从串开头和结尾向另一端查找第一个不为0的元素的位置
        //保存在start和end里头
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        for(int i=1;i<=n;i++)
        {
            if(a[i]!=0)
            {
                start=i;
                break;
            }

        }
        for(int i=n;i>=1;i--)
        {
            if(a[i]!=0)
            {
                end=i;
                break;
            }
        }
        //如果是1计数+1 如果是孤立的0(即0的左右均不为0) 计数+1
        last=a[start-1];
        for(int i=start;i<=end;i++)
        {
            if(last!=0&&a[i]==0&&a[i+1]!=0)
            {
                count++;
                last=a[i];
                continue;
            }
            else
                last=a[i];
            if(a[i]==1)
            {
                count++;
                last=a[i];
            }
        }

        printf("%d\n",count);
    }
}

Problem B: 小红帽
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 41 Solved: 11

Submit Status Web Board
Description
小红帽的故事大家都知道吧。现在妈妈又给小红帽一个任务,要去给奶奶送药。而狼依然狡猾,但是自从上次事件后,去姥姥家的路上开始多了几条秘密地道,这些地道狼是无法找到的,小红帽可以在这些地道中自由穿行(可以从任意地道口进,任意地道口出,地道都联通)。所以走这些地道非常安全。妈妈为了小红帽的安全,所以找来了地图。假设现在地图是一条直线,代表路上的情况,问你小红帽是否能安全(即不遇见狼)的到达姥姥家。

Input
输入第一行一个T,代表样例数。

接下来T行字符串(长度<=100),每行代表一个地图。地图上’S’代表小红帽的家,’T’代表姥姥家,’D’代表地道,’W’代表狼,其他用’.’表示(小红帽也可以走)。

Output
输出T组,每组首先”Case #X: Y.”,X代表第几组,’Y’代表’YES’或’NO’,输出’YES’,如果小红帽可以安全到达姥姥家。否则输出’NO’;

Sample Input
3
WS…TD
WTDWWW…SD
DSD….WT
Sample Output
Case #1: YES.
Case #2: YES.
Case #3: NO.

题意:W代表大灰狼、S代表起点、T代表终点、D是地道,任意的两个D间可以理解为能瞬移,比如DWD,小萝莉在左边第一个位置就可以瞬移到右边第一个D的位置,酱紫大灰狼就抓不到小萝莉,啊不对是小红帽了。
分析之后可以发现,如果能在T的左右两边的任意一边不经过W找到一个D且能在S的左右两边的任意一边不经过W找到一个D就是YES否则NO。

#include "cstring"
#include "cstdio"
#include "iostream"
#include "string.h"
using namespace std;

int min(int a,int b)
{
    return a>b?b:a;
}
int max(int a,int b)
{
    return a>b?a:b;
}

int main()
{
    int t;
    scanf("%d",&t);
    int cnt=0;
    while(cnt++<t)
    {
        char road[1000];
        int flag=1,pos_d1=0,pos_d2=0;
        scanf("%s",road);
        int i;
        int len=strlen(road);
        int pos_s,pos_t;
        for(i=0;i<len;i++)
        {
            if(road[i]=='S')pos_s=i;
            if(road[i]=='T')pos_t=i;
        }

        for(i=min(pos_s,pos_t);i<max(pos_s,pos_t);i++)
        {
            if(road[i]=='W')
            {
                flag=0;
                break;
            }
        }
        if(flag==0)
        {
            for(i=pos_s+1;i<len;i++)
            {
                if(road[i]=='W')
                    break;
                if(road[i]=='D')
                    pos_d1=1;
            }
            if(pos_d1==0)
            {
                for(i=pos_s-1;i>=0;i--)
                {
                    if(road[i]=='W')
                        break;
                    if(road[i]=='D')
                        pos_d1=1;
                }
            }
            for(i=pos_t+1;i<len;i++)
            {
                if(road[i]=='W')
                    break;
                if(road[i]=='D')
                    pos_d2=1;
            }
            if(pos_d2==0)
            {
                for(i=pos_t-1;i>=0;i--)
                {
                    if(road[i]=='W')
                        break;
                    if(road[i]=='D')
                        pos_d2=1;
                }
            }
            if(pos_d1==1&&pos_d2==1)flag=1;
        }
        if(flag)
            printf("Case #%d: YES.\n",cnt);
        else
            printf("Case #%d: NO.\n",cnt);
    }
    return 0;
}

Problem C: 1-2-B
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 35 Solved: 12

Submit Status Web Board
Description
One day Misha and Andrew were playing a very simple game. First, each player chooses an integer in the range from 1 to n. Let’s assume that Misha chose number m, and Andrew chose number a.

Then, by using a random generator they choose a random integer c in the range between 1 and n (any integer from 1 to n is chosen with the same probability), after which the winner is the player, whose number was closer to c. The boys agreed that if m and a are located on the same distance from c, Misha wins.

Andrew wants to win very much, so he asks you to help him. You know the number selected by Misha, and number n. You need to determine which value of a Andrew must choose, so that the probability of his victory is the highest possible.

More formally, you need to find such integer a (1 ≤ a ≤ n), that the probability that |c - a| < |c - m| is maximal, where c is the equiprobably chosen integer from 1 to n (inclusive).

Input
The first line contains two integers n and m (1 ≤ m ≤ n ≤ 109) — the range of numbers in the game, and the number selected by Misha respectively.

Output
Print a single number — such value a, that probability that Andrew wins is the highest. If there are multiple such values, print the minimum of them.

Sample Input
3 1
4 3
Sample Output
2
2

题意:有个区间1~n,两个人玩游戏Misha挑一个数字m,Andrew挑一个数字a。另外有一个在1~你上的随机数c。获胜规则是a,m哪个离c近哪个就赢。如果两个距离一样算Misha赢。给你n和m,问a值多少让Andrew赢的概率大。(如果有多个a值输出小的那个)
分析后发现只要判断m落在1~n的左半区间还是右半区间,如果在左半区间a=m+1因为c落在a右侧的概率比落在左侧的大,同理落在右半区间时a=m-1,另外有些特殊情况我就懒得说了比如n奇偶时不一样,还有处理多值输出小的问题,大家直接看代码吧。

#include "cstring"
#include "cstdio"
#include "iostream"
#include "string.h"

using namespace std;

int main()
{
    int n,m;
    while(scanf("%d",&n)!=EOF)
    {
        scanf("%d",&m);
        if(n==1)
        {
            printf("1\n");
            continue;
        }


        if(n%2==1)
        {
            if(m==(n+1)/2)
            {
                printf("%d\n",(n+1)/2-1);
                continue;
            }
        }
        if(n%2==1)
        {
            if((double)m<(double)n*1.0/2.0)
            {
                printf("%d\n",m+1);
            }
            else
            {
                printf("%d\n",m-1);
            }

        }
        else
        {
            if((double)m<(double)(n*1.0/2.0)+0.5)
            {
                printf("%d\n",m+1);
            }
            else
            {
                printf("%d\n",m-1);
            }

        }


    }
}

Problem D: 哈夫曼
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 9 Solved: 7

Submit Status Web Board
Description
1111这一天,Javac++ 一天在看计算机的书籍的时候,看到了一个有趣的东西!每一串字符都可以被编码成一些数字来储存信息,但是不同的编码方式得到的储存空间是不一样的!并且当储存空间大于一定的值的时候是不安全的!所以Javac++ 就想是否有一种方式是可以得到字符编码最小的空间值!显然这是可以的,因为书上有这一块内容–哈夫曼编码(Huffman Coding);一个字母的权值等于该字母在字符串中出现的频率。所以Javac++ 想让你帮忙,给你安全数值和一串字符串,并让你判断这个字符串是否是安全的?

Input
输入有多组case,首先是一个数字n表示有n组数据,然后每一组数据是有一个数值m(integer),和一串字符串没有空格只有包含小写字母组成!

Output
如果字符串的编码值小于等于给定的值则输出yes,否则输出no。

Sample Input
2
12
helloworld
66
ithinkyoucandoit
Sample Output
no
yes

题意:哈弗曼树嘛,就是每次找最小的两个结点合并生成一个新的父亲结点。然后这题就是把哈弗曼树除叶子结点以外的所有节点加起来和所给的最大存储空间比一下就是答案了。
我是用优先队列写的,用set也可以,set的迭代器跟我不熟我还是不作死了。

这题是HDU2527刚才去杭电上交了一下,WA了好几发,这题有坑啊!只有一个节点的时候也要判啊!!!
像这样
4
5
aaaaa
yes
5
aaaaaa
no
还有就是怕爆最后的结果爆int所以改了一下long long

#include "cstring"
#include "cstdio"
#include "string.h"
#include "iostream"
#include "queue"
#include "vector"
#include "algorithm"

using namespace std;
struct cmp  //优先队列需要的排序函数,升序
{
    bool operator()(long long &a,long long &b)
    {
        return a>b;
    }
};

int main()
{
    int ncase;
    scanf("%d",&ncase);
    while(ncase--)
    {
        int max;
        scanf("%d",&max);
        char a[1500];
        long long cnt[27];
        memset(cnt,0,sizeof(cnt));
        scanf("%s",a);
        //统计每个字母出现的次数
        for(int i=0;;i++)
        {
            if(a[i]=='\0')
                break;
            cnt[a[i]-'a']++;
        }

        priority_queue<long long,vector<long long>,cmp> list;

        for(int i=0;i<=25;i++)
        {
            if(cnt[i]!=0)
                list.push(cnt[i]);
        }

        long long sum=0;
        if(list.size()==1)
        {
            sum=list.top();
            if(sum<=(long long)max)
                printf("yes\n");
            else
                printf("no\n");
            continue;
        }
        while(!list.empty()&&list.size()!=1)
        {
            long long temp1=list.top();
            list.pop();
            long long temp2=list.top();
            list.pop();
            long long temp3;
            temp3=temp2+temp1;
            list.push(temp3);
            sum+=temp3;

        }
        if(sum<=(long long)max)
            printf("yes\n");
        else
            printf("no\n");

    }

}

最后一题不会做 你们问二狗和方巨巨

你可能感兴趣的:(GoldCoder(金狗杯——福师大周赛) Run #2 题解)