【bestcoder #36】ABCD题解

Strange Class

Accepts: 519 Submissions: 1749

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

问题描述

在Vivid的学校里,有一个奇怪的班级(SC).在SC里,这些学生的名字非常奇怪。他们的名字形式是这样的anbncn(a,b,c两两不相同。).例如,叫”abc”,”ddppqq”的学生是在SC里的,然而叫”aaa”,”ab”,”ddppqqq”的同学并不是在SC里的。

Vivid交了许多的朋友,他想知道他们之中哪些人是在SC里的。

输入描述

多组测试数据(大概10组),每一个数据在一行中给出一个字符串S,代表Vivid一个朋友的名字。

请处理到文件末尾。

[参数约定]

1≤|S|≤10.

|S| 是指S的长度.

S 只包含小写字母.

输出描述

对于每一个数据,如果Vivid的朋友是SC里的,那么输出YES,否则输出NO。

输入样例

abc

bc

输出样例

YES

NO

WA两次才过,第一次没看到abc必须是连续的;第二次没看到abc必须两两不同。

#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
char s[100];
int cnt[100];
int main()
{
    while (scanf("%s",s)!=EOF)
    {
        for (int i=1;i<=30;i++)
            cnt[i]=0;
        int l=strlen(s);
        int num=0;
        if (l<3)
        {
            cout<<"NO"<<endl;
            continue;
        }
        int k;
        int now=0,f=1;
        while (now<l)
        {
            int x=now;
            while (now+1<l&&s[now]==s[now+1])
                now++;
            num++;
            if (cnt[s[now]-‘a‘+1]) f=0;
            else cnt[s[now]-‘a‘+1]=1;
            if (num==1) k=now-x+1;
            else
            {
                if (now-x+1!=k) f=0;
            }
            now++;
        }
        if (num!=3||!f)
        {
            cout<<"NO"<<endl;
        }
        else
        {
            cout<<"YES"<<endl;
        }
    }
    return 0;
}

Gunner

Accepts: 391 Submissions: 1397

Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

问题描述

很久很久以前,有一个叫Jack的枪手。他非常喜欢打猎。一天,他去了一个小树林。那儿有n只鸟,还有n棵树。第i只鸟站在第i棵树的顶端。这些树从左到右排成一条直线。每一棵树都有它的高度。Jack站在最左边那棵树的左边。当Jack在高度为H的地方向右发射一棵子弹时,站在高度为H的树上的鸟儿就会落下来。

Jack会射击多次,他想知道每次射击会有多少鸟儿落下来。

输入描述

多组测试数据(大概5组),每一组的第一行给出n,m,n表示有n棵树和n只鸟,m表示Jack会射击m次。

在第二行,有n个整数, h[1],h[2],h[3],…,h[n]表示这些树的高度。

在第三行,有m个整数, q[1],q[2],q[3],…,q[m]表示Jack射击的高度。

[参数约定]

1≤n,m≤1000000(106)

1≤h[i],q[i]≤1000000000(109)

输出描述

对于每一个q[i],在一行中输出Jack射落了几只鸟。

输入样例

4 3

1 2 3 4

1 1 4

输出样例

1

0

1

Hint

大数据输入,推荐使用快速读读入。

我是用map水过的。

正解是将原来的树从高到低排序,然后每次询问二分查找一段区间。

注意在找到之后,要将其删掉。

#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <set>
#include <map>
using namespace std;
map<int,int> mp;
int n,m,cnt[1000010];
void read(int &tmp)
{
    int ch=getchar();
    int fu=1;
    tmp=0;
    for (;ch<‘0‘||ch>‘9‘;ch=getchar())
        if (ch==‘-‘) fu=-1;
    for (;ch>=‘0‘&&ch<=‘9‘;ch=getchar())
        tmp=tmp*10+ch-‘0‘;
    tmp*=fu;
}
int main()
{
    while (scanf("%d%d",&n,&m)!=EOF)
    {
        mp.clear();
        for (int i=1;i<=1000005;i++)
            cnt[i]=0;
        for (int i=1;i<=n;i++)
        {
            int x;
            read(x);
            if (!mp[x]) mp[x]=i;
            cnt[mp[x]]++;
        }
        for (int i=1;i<=m;i++)
        {
            int x;
            read(x);
            printf("%d\n",cnt[mp[x]]);
            cnt[mp[x]]=0;
        }
    }
    return 0;
}

Trees

Accepts: 156 Submissions: 533

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

问题描述

今天CodeFamer去坎树。有N棵树排成一排。他们被从1到N标号。第i号树的高度为hi。两棵未被坎掉的树编号分别为x,y当且仅当他们满足如下条件中一条时,他们是属于同一个块的:

1) x+1=y 或 y+1=x;

2) 存在一个棵未被坎掉的树,编号为z,x和z在同一个块并且y和z也在同一个块。

现在CodeFamer想要坎掉一些高度不大于某个值的树,坎掉之后会形成多少个块呢?

输入描述

多组测试数据(大概15组)

对于每一组数据,第一行包含两个整数N和Q,以一个空格分开,N表示有N棵树,Q表示有Q个查询。

在接下来的N行中,会出现h[1],h[2],h[3],…,h[N],表示N棵树的高度。

在接下来的Q行中,会出现q[1],q[2],q[3],…,q[Q]表示CodeFamerr查询。

请处理到文件末尾。

[参数约定]

1≤N,Q≤50000

0≤h[i]≤1000000000(109)

0≤q[i]≤1000000000(109)

输出描述

对于每一个q[i],输出CodeFamer坎掉高度不大于q[i]的树之后有多少个块。

输入样例

3 2

5

2

3

6

2

输出样例

0

2

Hint

在这个样例中,有3棵树,他们的高度依次是5 2 3。

对于6这个查询,如果CodeFamer坎掉高度不大于6的树,那么剩下的树高度形状是-1 -1 -1(-1表示那个树被坎掉了)。这样就有0个块。

对于2这个查询,如果CodeFamer坎掉高度不大于2的树,那么剩下的树高度形状是5 -1 3(-1表示那个树被坎掉了)。这样就有2个块。

思路题。

离线来做。

首先把树的标记ok[i]置为1,表示他们都没有被砍;

按照树高将读入排序,把询问也按照树高排序,当前的ans=1。

依次处理询问,由于询问是升序的,那么一定是按照当前树的顺序砍的。

当要砍掉第i棵树的时候,ok[i]=0,判断:

1.ok[i-1]=1,ok[i+1]=1,说明砍掉这棵树就会多一块,ans++

2.ok[i-1]=0,ok[i+1]=0,说明这棵树本来就是一块,砍掉之后ans–

3.ok[i-1]^ok[i+1]=1,砍掉这棵树对块数没有任何影响

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <cstdio>
using namespace std;
struct data
{
    int v,id,ans;
}h[50005],q[50005];
int n,Q,ok[50005];
void read(int &tmp)
{
    int ch=getchar();
    int fu=1;
    tmp=0;
    for (;ch<‘0‘||ch>‘9‘;ch=getchar())
        if (ch==‘-‘) fu=-1;
    for (;ch>=‘0‘&&ch<=‘9‘;ch=getchar())
        tmp=tmp*10+ch-‘0‘;
    tmp*=fu;
}
bool cmp(data a,data b)
{
    return a.v<b.v;
}
bool cmpp(data a,data b)
{
    return a.id<b.id;
}
int main()
{
    while (scanf("%d%d",&n,&Q)!=EOF)
    {
        ok[0]=0,ok[n+1]=0;
        for (int i=1;i<=n;i++)
            ok[i]=1,read(h[i].v),h[i].id=i;
        sort(h+1,h+1+n,cmp);
        for (int i=1;i<=Q;i++)
            read(q[i].v),q[i].id=i;
        sort(q+1,q+1+Q,cmp);
        int now=0;
        int ans=1;
        for (int i=1;i<=Q;i++)
        {
            while (h[now+1].v<=q[i].v&&now+1<=n)
            {
                int x=h[now+1].id;
                ok[x]=0;
                if (ok[x-1]&&ok[x+1]) ans++;
                if (!ok[x-1]&&!ok[x+1]) ans--;
                now++;
            }
            q[i].ans=ans;
        }
        sort(q+1,q+1+Q,cmpp);
        for (int i=1;i<=Q;i++)
            printf("%d\n",q[i].ans);
    }
    return 0;
}

The Monkey King

Accepts: 19 Submissions: 71

Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

问题描述

就像大家所知道的,美猴王的名字叫孙悟空。他和他的后代们生活在花果山。一天,他的儿子得到了n个桃子。现在他们有m个猴子(包括悟空在内),他们被从1到m标号,悟空的号码是1。悟空想把这些桃子分给他们自己。由于悟空是大王,所以他获得的桃子必须是最多的。悟空想知道有多少种不同的分配方法。

例如n=2,m=3的时候,只有一种分法2 0 0。

当给定n,m时,你的任务是计算悟空可以有多少种不一样的方法来分配这些桃子。由于答案比较大输出对1000000007取余的结果即可。

输入描述

多组测试数据。在输入文件的第一行有一个整数T,表示有T组数据。

在接下来的T行,每行包含n和m。他们的含义在上边已经提到。

[Technical Specification]

所有输入均为整数。

1≤T≤25

1≤n,m≤100000

输出描述

对于每一个数据在一行中输出答案。

查看样例可以获得更多信息。

输入样例

2

2 2

3 5

输出样例

1

5

Hint

第二组样例中有5种分配方案,他们是

2 1 0 0 0

2 0 1 0 0

2 0 0 1 0

2 0 0 0 1

3 0 0 0 0

容斥原理+多重集的排列组合~

(前两天刚做过一道【BZOJ 1272】,考试却没想出来TT)

枚举悟空分得的桃子数为i,那么其他人分得的桃子数都要<i,求其他人分得桃子数<i的分法用容斥原理:

无任何限制的分法?(有一只猴子≥i的分法)+(有两只猴子≥i的分法)…

如何计算有n?i个桃子分给m?1只猴子,其中有j只猴子分得的桃子≥i的分法?

首先选出j只猴子C(m?1,j),那么i?j个桃子已经有了归属。

问题变成了将n?i?i?j个桃子分给m?1只猴子,用隔板法!

桃子看成1,猴子看成0,相当于用m?2个0把n?i?i?j个1分成m?1段,即

C(n?i?i?j+m?2,m?2)

最后的答案就是

C(m?1,j)?C(n?i?i?j+m?2,m?2)

这样两层枚举看起来是O(n2)的复杂度,实际上是n+n2+n3+n4+?=nlogn的~

时间: 2025-01-02 15:30:07

【bestcoder #36】ABCD题解的相关文章

bestcoder#36 1002 哈希

bestcoder#36 1002 哈希 Gunner Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 726    Accepted Submission(s): 326 Problem Description Long long ago, there is a gunner whose name is Jack. He likes t

BestCoder Round #11 题解集合

1001.Alice and Bob 签到题*1,只要x * 2 == n && y * 2 == m就满足条件. 1 var 2 m, n, x, y : int64; 3 4 begin 5 while not eof do begin 6 readln(m, n, x, y); 7 if (m = 2 * x) and (n = 2 * y) then writeln('YES') else writeln('NO'); 8 end; 9 end. 1002.Bob and math

BestCoder 1st Anniversary ($) 题解

Souvenir 问题描述 今天是BestCoder一周年纪念日. 比赛管理员Soda想要给每个参赛者准备一个纪念品. 商店里纪念品的单价是p元, 同时也可以花q元购买纪念品套装, 一个套装里有m个纪念品. 今天总共有n个参赛者, Soda想要知道最少需要花多少钱才可以给每个人都准备一个纪念品. 输入描述 输入有多组数据. 第一行有一个整数T (1≤T≤105), 表示测试数据组数. 然后对于每组数据: 一行包含4个整数 n,m,p,q (1≤n,m,p,q≤104). 输出描述 对于每组数据输

【codeforces #278(div 1)】ABCD题解

A. Fight the Monster time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output A monster is attacking the Cyberland! Master Yang, a braver, is going to beat the monster. Yang and the monster each hav

【codeforces #286(div 2)】ABCD题解

这次rank23~又回到紫名啦~ A.枚举插入的位置和插入的字符,暴力判断即可. #include <iostream> #include <cmath> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <string> using namespace std; string S; int s[20]

Codeforces Round #533 (Div. 2) ABCD 题解

题目链接 A. Salem and Sticks 分析 暴力就行,题目给的n<=1000,ai<=100,暴力枚举t,t从2枚举到98,复杂度是1e5,完全可行. 代码 1 #include <cstdio> 2 #include <cmath> 3 #include <iostream> 4 #include <cstring> 5 #include <algorithm> 6 #include <vector> 7 #

codeforces #593 div2 ABCD 题解

A. Stones Description 给出3堆物品,个数分别为a,b,c 有两种取数方式,a1b2,b1c2,问最多取多少物品 Solution $O(n^2)暴力$ 1 #include <algorithm> 2 #include <cctype> 3 #include <cmath> 4 #include <cstdio> 5 #include <cstdlib> 6 #include <cstring> 7 #inclu

Educational Codeforces Round 75 ABCD题解

A. Broken Keyboard Description 给出一串小写字母字符序列,连续出现两次的字母为坏掉的,按字典序输出所有没有坏掉的字母. Solution 模拟暴力删除字母,注意相同字母的去重. 1 #include <algorithm> 2 #include <cctype> 3 #include <cmath> 4 #include <cstdio> 5 #include <cstdlib> 6 #include <cst

Codeforces Round #250 (Div. 2) (ABCD题解)

比赛链接:http://codeforces.com/contest/433 A. Kitahara Haruki's Gift time limit per test:1 second memory limit per test:256 megabytes Kitahara Haruki has bought n apples for Touma Kazusa and Ogiso Setsuna. Now he wants to divide all the apples between th