链接:
http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1107
题目:
Description
想必大家已经领略了店长的调皮,自从店长知道了vagaa之后就一直沉迷期中不能自拔,教主看到后很是伤心,玩物丧志啊!于是教主教店长了一个vagaa的新用法,资源搜索功能。输入一些关键词后可以搜索出相关共享的好资源,店长得知后又是欣喜若狂。同时,教主又发明一个游戏,是上次的升级版,这次给出一些由字母和数字的玩具的同时,关键字不再是vagaa了,需要自己给出.看最后能组成多少个关键字。
Input
每行输入一个字符串由小写字母和数字组成,每个字符代表一个玩具, 紧接着输入一个关键字,同样由字母和数字组组成,字符串长度0<n<=10000,关键字长度0<m<=200
处理到文件结束
Output
输出能够组成关键字的数量
按照样例输出格式输出并换行.
Sample Input
vagaadsfaagav ga
asgvasdfzxcades dea
Sample Output
Case 1: 2
Case 2: 1
解题分析:
思路一:错误
将关键字中的每个字符和给定的字符串中的字符 一 一 匹配,相同则计数器加1,存到数组中,但是会出现一个问题就是只要匹配到之前的也会数算进来,导致数组中第一个之后数都是累计前面的,那么就将前面的减去,再开一个数组来存,但是又出现一个问题,就是关键字中的字符若是全为一样的,比如关键字 key = “aaa”,给定的主串是 s = "abcd",结果应该是“0” ,但是不尽然,计数器存到数组中却是1,2,3。转化到另一数组中却是1 ,1 ,1 ,这个问题目前我想不到解决办法。
代码:
#include<bits/stdc++.h> using namespace std; char a[10005]; char key[205]; int c[205]; int d[205]; int main() { int cas = 0; while(~scanf("%s%s",&a,&key)) { printf("Case %d: ",++cas); memset(c,0,sizeof(c)); memset(d,0,sizeof(d)); int lena = strlen(a); int lenk = strlen(key); int count = 0; int cnt = 0; for(int i = 0; i < lenk; i++) { for(int j = 0 ; j < lena; j++) { if(key[i] == a[j]) count++; } c[cnt++] = count; } for(int i = 0; i < cnt; i++) { for(int j = 0; j < cnt; j++) { d[0] = c[0]; if(i != 0) { d[i] = c[i] - c[i-1]; } } } sort(d,d+cnt); printf("%d\n",d[0]); } return 0; }
思路二:正确
因为题目中的串只有字母和数字组成,所以可以直接来分开处理,用数组来数字和字母的每个状态下的个数即可
代码:
#include<bits/stdc++.h> using namespace std; char a[10005]; char key[205]; int arrA[205]; int arrK[205]; int cnt1,cnt2; int main() { int cas = 0; while(~scanf("%s%s",&a,&key)) { memset(arrA,0,sizeof(arrA)); memset(arrK,0,sizeof(arrK)); int lena = strlen(a); //处理主串 for(int i = 0; i < lena; i++) { //数字 if(a[i] >= '0' && a[i] <= '9') { cnt1 = a[i] - '0'; //一个状态的标记,以便之后相同的状态个数++ arrA[cnt1]++; } //字母 else { cnt1 = a[i]-'a'+10;//此处加10是为了和数字区别开,否则状态混淆 arrA[cnt1]++; } } //处理关键串 int lenk = strlen(key); for(int i = 0; i < lenk; i++) { //数字 if(key[i] >= '0' && key[i] <= '9') { cnt2 = key[i] - '0'; arrK[cnt2]++; } //字母 else { cnt2 = key[i] - 'a' + 10; arrK[cnt2]++; } } int ans = 99999; for(int i = 0 ; i < 36 ; i++) { if(arrK[i] > 0) { int temp; temp = arrA[i]/arrK[i]; if(temp < ans) ans = temp; } } printf("Case %d: %d\n",++cas,ans); } return 0; }