UVA - 409 Excuses, Excuses!

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19139

做字符串的题总是如此费力,就更加说明了自己编程能力很欠缺,总是不能让问题简化,而是更加复杂化,抓不住问题的核心,像学长说的,要善于总结,并且要用最精简的代码,任重道远啊!

这道题还是水题,先给定n个字符串,然后给定m行字符串,让你输出n个字符串出现次数最多的那一行字符串,注意不区分大小写,所以可以把每一行字符都预处理成小写字母,

关键点在于 这句话    A keyword ``occurs" in an excuse if and only if it exists in the string in contiguous form and is delimited by the beginning or end of the line or any non-alphabetic character or a space.   

我开始一直没明白什么意思,自然导致不停的wrong,但是后来意识到,一个字符串在一行中出现前后都是不能有字母的,和平时习惯一样,注意这点就没难度了。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val)    memset(arr, val, sizeof(arr))

#define ll long long
#define inf 0x7f7f7f7f
#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)

#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   (l + r) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)        (1 << (x))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define lowbit(x)   (x)&(-x)
#define Read()  freopen("a.txt", "r", stdin)
#define Write() freopen("dout.txt", "w", stdout);
#define N 100005
using namespace std;

int solve(char *s2,char *s1)
{
    int i,k,ans=0;  //s1是关键词,s2是当前要查找的行
    int l1=strlen(s1),l2=strlen(s2);
    for(i=0;i<l2;i++)
    {
        if(s2[i]==s1[0]&&(!(s2[i-1]>='a'&&s2[i-1]<='z'))) //保证前面不是字母
        {
            for(k=1;k<l1;k++)  //然后依次判断后面的字符
                if(s1[k]!=s2[i+k]) break;
            if(!(s2[i+l1]>='a'&&s2[i+l1]<='z')&&k==l1) ans++; //保证后面不是字母
        }
    }
    return ans;
}
int main()
{
   //Read();
   int n,m,i,j,k=1;
   int f[25];
   char s1[25][100],s2[25][100],s3[25][100];
   while(~scanf("%d%d",&n,&m))
   {
       getchar();
       CL(f,0);
       CL(s3,0);
       for(i=0;i<n;i++)
       {
            gets(s1[i]);
       }
       for(i=0;i<m;i++)
       {
           gets(s2[i]);
           strcpy(s3[i],s2[i]);  //把每一行都预先保存下来,输出的时候要用
           int l=strlen(s2[i]);
           for(j=0;j<l;j++)
           if(isupper(s2[i][j])) s2[i][j]=tolower(s2[i][j]); //转换成小写字母
       }
        int ans;
        for(i=0;i<m;i++)
        {   //两重循环枚举字符串在一行中出现的字数
            for(j=0;j<n;j++)
            {
                ans=0;
                ans=solve(s2[i],s1[j]);
                f[i]+=ans; //ans返回出现次数,f[i]保存关键词在第i行总共出现的次数
            }
        }
        ans=0;
       for(i=0;i<m;i++)
       {
           if(f[i]>ans) ans=f[i]; //找出出现次数最多 的
       }
       printf("Excuse Set #%d\n",k++);
       for(i=0;i<m;i++)
       {
           if(f[i]==ans) printf("%s\n",s3[i]);
       }
       printf("\n");
   }
   return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值