2016"百度之星" - 资格赛(Astar Round1)

来源:互联网 发布:指南针炒股软件好用吗 编辑:程序博客网 时间:2024/05/17 22:51

度熊面前有一个全是由1构成的字符串,被称为全1序列。你可以合并任意相邻的两个1,从而形成一个新的序列。对于给定的一个全1序列,请计算根据以上方法,可以构成多少种不同的序列。
Input

这里包括多组测试数据,每组测试数据包含一个正整数NNN,代表全1序列的长度。

1≤N≤2001\leq N \leq 2001≤N≤200
Output

对于每组测试数据,输出一个整数,代表由题目中所给定的全1序列所能形成的新序列的数量。
Sample Input

1
3
5

Sample Output

1
3
8

Hint

如果序列是:(111)。可以构造出如下三个新序列:(111), (21), (12)。
分析:容易的到公式:f(N)=f(n-1)+f(n-2);但是long long 也不够用 只能模拟下大数相加了!

#include<iostream>#include<cstring>#include<algorithm>#include<string>#include<cmath>using namespace std;long long a[500][500]={0};void init(){    a[0][0]=1,a[1][0]=1;    for(int i=2;i<=200;i++)    {        int len1=0,len2=0;        for(int j=400;j>=0;j--)        {           if(a[i-1][j]!=0)           {               len1=j;           break;           }        }        for(int j=400;j>=0;j--)        {            if(a[i-2][j]!=0)            {               len2=j;                break;                }        }        int len3=max(len1,len2);        for(int j=0;j<=len3;j++)        {            a[i][j]=a[i-1][j]+a[i-2][j];        }        for(int j=0;j<=len3;j++)        {            if(a[i][j]>9)            {            a[i][j+1]+=a[i][j]/10;            a[i][j]%=10;            }        }        while(a[i][len3+1]>0)        {            len3++;            a[i][len3+1]+=a[i][len3]/10;            a[i][len3]%=10;        }    }}int main(){    init();    int t,k;    while(cin>>t)    {    for( k=400;;k--)    {    if(a[t][k]>0)    break;    }    for(;k>=0;k--)    cout<<a[t][k];     cout<<endl;    }    return 0;}

度熊手上有一本神奇的字典,你可以在它里面做如下三个操作:

1、insert : 往神奇字典中插入一个单词

2、delete: 在神奇字典中删除所有前缀等于给定字符串的单词

3、search: 查询是否在神奇字典中有一个字符串的前缀等于给定的字符串

Input

这里仅有一组测试数据。第一行输入一个正整数N(1≤N≤100000)N (1\leq N\leq 100000)N(1≤N≤100000),代表度熊对于字典的操作次数,接下来NNN行,每行包含两个字符串,中间中用空格隔开。第一个字符串代表了相关的操作(包括: insert, delete 或者 search)。第二个字符串代表了相关操作后指定的那个字符串,第二个字符串的长度不会超过30。第二个字符串仅由小写字母组成。
Output

对于每一个search 操作,如果在度熊的字典中存在给定的字符串为前缀的单词,则输出Yes 否则输出 No。
Sample Input

5
insert hello
insert hehe
search h
delete he
search hello

Sample Output

Yes
No
分析:很容易想到用字典树,难点在于删除操作。这点的话:对于删除s1,对于s1本身,减去以它为前缀它的次数,对于以它为前缀的字符直接删除。

#include<iostream>#include<algorithm>#include<cstring>#include<string>#include<cmath> using namespace std;struct Trie   {       Trie *next[26];       int v;   //根据需要变化    Trie() {        memset(next,0,sizeof(next));        v=0;    }};   struct Trie *root;   void createTrie(char *str){    int len = strlen(str);    struct Trie *p , *q;    p=root;    for(int i=0; i<len; ++i)    {        int id = str[i]-'a';        if(p->next[id] == NULL)        {            p->next[id]=new Trie;       }        p = p->next[id];       p->v++;   }}int findTrie(char *str){    int len = strlen(str);    Trie *p = root;    for(int i=0; i<len; ++i)    {        int id = str[i]-'a';        p = p->next[id];        if(p == NULL)               return 0;    }    return p->v ;}int main(){    char s1[100],s2[100];    int t;    scanf("%d",&t);    root=new Trie;    while(t--)    {        scanf("%s",s1),scanf("%s",&s2);        if(strcmp(s1,"insert")==0)        {            createTrie(s2);        }        else if(strcmp(s1,"search")==0)        {            int k=findTrie(s2);            if(!k)            cout<<"No"<<endl;            else            cout<<"Yes"<<endl;            }        else if(strcmp(s1,"delete")==0)        {                int flag=0;             Trie *s3;             s3=root;            int len=strlen(s2);            int k=findTrie(s2);            if(k)            {            for(int i=0;i<len;i++)            {                int idx=s2[i]-'a';                 s3=s3->next[idx];                s3->v-=k;            }            for(int i=0;i<26;i++)            s3->next[i]=NULL;            }        }    }    return 0;}

度熊所居住的 D 国,是一个完全尊重人权的国度。以至于这个国家的所有人命名自己的名字都非常奇怪。一个人的名字由若干个字符组成,同样的,这些字符的全排列的结果中的每一个字符串,也都是这个人的名字。例如,如果一个人名字是 ACM,那么 AMC, CAM, MAC, MCA, 等也都是这个人的名字。在这个国家中,没有两个名字相同的人。

度熊想统计这个国家的人口数量,请帮助度熊设计一个程序,用来统计每一个人在之前被统计过多少次。
Input

这里包括一组测试数据,第一行包含一个正整数NNN,接下来的NNN 行代表了 NNN 个名字。NNN 不会超过100,000100,000100,000,他们的名字不会超过40位.
Output

对于每输入的一个人名,输出一个整数,代表这个人之前被统计了多少次。
Sample Input

5
ACM
MAC
BBA
ACM
BAB

Sample Output

0
1
0
2
1

#include<iostream>#include<algorithm>#include<string>#include<cstring>#include<map>using namespace std;int  main(){    string s;    int t;    cin>>t;    map<string,int> m;    while(t--)    {        cin>>s;        sort(s.begin() ,s.end());         if(m.find(s)!=m.end())         {             cout<<m[s]<<endl;                 m[s]++;         }         else         {             m[s]=1;             cout<<"0"<<endl;         }    }    return 0;}
0 0
原创粉丝点击