度熊面前有一个全是由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
#include
#include
#include
#include
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<cout<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
#include
#include
#include
#include
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; iint 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; iint 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"<else
cout<<"Yes"<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;iint 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
#include
#include
#include
#include
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<else
{
m[s]=1;
cout<<"0"<return 0;
}