CodeForces - 589A(字符串处理)

题目链接http://codeforces.com/problemset/problem/589/A

题目大意:给定n个邮件地址,任何电子邮件地址都将显示为“login @ domain”,其中:

1.a“login”是一个由非空的小写和大写字母序列以及点(‘.‘)和加号(‘+‘)组成的序列,从字母开始;
2.a“domain”是一个由非空的小写和大写字母和点组成的序列,因为点将序列分成非空单词,仅由字母组成(即“domain”从字母开始,以字母结尾,不包含两个或多个连续点)。

比较邮件地址时,不考虑字符的大小写。此外,在比较bmail.com地址时,服务器会忽略登录中的点以及电子邮件地址登录部分中第一个字符“加”(“+”)到字符“at”(“@”)的所有字符。

在给定n个邮件地址后,让你输出每个邮件地址出现的次数与所有这个邮箱的原始串。

例:

输入:

6
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]

输出:

4
2 [email protected] [email protected]
2 [email protected] [email protected]
1 [email protected]
1 [email protected]

解题思路:题目有点长,理解题目理解了老半天。题目好像没有涉及什么算法,不过对代码能力好像要求还是有点的,看了别人的代码才好不容易码出来了。。。做法大概就是直接定义一个结构体数组,用来存储每个字符串的原字符串和忽略那些不必要的变形之后的字符串,以及存储他们所在的位置下标。先排序将变形后相同的字符串排在相邻的位置,然后将变形后相同的字符串的下标存到一个ans向量组里,向量的大小即为该字符串相同的数量。输出时再将结构体数组排成初始顺序即可。

附上代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<vector>
 6 using namespace std;
 7 struct node{
 8     string s;  //存储原字符串
 9     string change;  //存储改变之后的字符串
10     int id;  //存储位置下标
11 }st[20005];
12 vector<int> ans[20005];  //相同字符串的下标存在同一个向量里面
13 int n;
14
15 bool comp(const node &a,const node &b)
16 { //相同的字符串排在一起
17     if(a.change==b.change)
18         return a.id<b.id;
19     return a.change<b.change;
20 }
21
22 bool comp1(const node &a,const node &b)
23 {  //恢复成它们的初始位置
24     return a.id<b.id;
25 }
26 int main()
27 {
28     while(cin>>n)
29     {
30         for(int i=0;i<n;i++)
31         {
32             cin>>st[i].s;
33             st[i].id=i;
34             ans[i].clear();
35         }
36         for(int i=0;i<n;i++)
37         {
38             string temp;
39             if(st[i].s.size()>=10)
40             {
41                 temp=st[i].s.substr(st[i].s.size()-10,10);  //如果字符串长度大于10则取出后10位字符,判断是否为"@bmail.com"
42                 for(int j=0;j<10;j++)
43                     temp[j]=towlower(temp[j]);  //将temp转换成小写
44                 //cout<<temp<<endl;
45             }
46             if(temp=="@bmail.com")//判断该字符串后10位是否为"@bmail.com"
47             {
48                 bool ok=false,ok1=false;
49                 for(int j=0;j<st[i].s.size();j++)
50                 {
51                     if(st[i].s[j]==‘@‘) ok=false,ok1=true;
52                     if(st[i].s[j]==‘+‘) ok=true;
53                     if((st[i].s[j]==‘.‘&&!ok1)||ok) continue;  //在第一个“+”至“@”内的不计
54                     st[i].change.push_back(towlower(st[i].s[j]));  //转换成小写
55                 }
56             }
57             else  //普通邮件地址,直接转换成小写
58             {
59                 for(int j=0;j<st[i].s.size();j++)
60                     st[i].change.push_back(towlower(st[i].s[j]));
61             }
62         }
63         sort(st,st+n,comp);
64         int cnt=0;
65         ans[0].push_back(st[0].id);
66         for(int i=1;i<n;i++)  //比较字符串是否相同,相同的下标放到同一个向量
67         {
68             if(st[i].change==st[i-1].change) ans[cnt].push_back(st[i].id);
69             else ans[++cnt].push_back(st[i].id);
70         }
71         sort(st,st+n,comp1);
72         cout<<cnt+1<<endl;
73         for(int i=0;i<=cnt;i++)
74         {
75             cout<<ans[i].size();  //向量的大小即为该相同字符串的数量
76             for(int j=0;j<ans[i].size();j++)
77                 cout<<" "<<st[ans[i][j]].s;
78             cout<<endl;
79         }
80     }
81     return 0;
82 }

原文地址:https://www.cnblogs.com/zjl192628928/p/9402494.html

时间: 2024-07-31 03:46:14

CodeForces - 589A(字符串处理)的相关文章

codeforces 589a(构造的字符串后,最后要加终止符,,,)

模拟注意细节,没什么好说的#include <cstdio> #include <cstring> #include <vector> #include <algorithm> #include <iostream> #include <map> #include <queue> #include <stack> #include <cmath> //#pragma comment(linker,

CodeForces 625B 字符串模拟+思维

题意 给出字符串a与b 可以将a中的单个字符改为# 问最少改多少次 a中就找不到b了 一开始想的是用strstr 因为如果找到 可以将strstr(a,b)-a+1改成# 即改首字母 用while循环strstr来做题 然而改第一个字母不行 因为有可能重叠 比如在lll之中找ll 改了第一个还能找出来 但是其实只改一个就可以了 之后又想是不是能改最后一个 但是用strstr不会... 所以最后想出了暴力扫一遍的神奇解法..因为最多 a是五次方 b是30 最多是3乘十的六次方..结果46ms就好了

Codeforces 898F 字符串hash

F. Restoring the Expression 题意:给出一个字符串,要把它折分成三部分 a.b.c , 使得 a+b=c .输出任何一种可行情况. tags:字符串 hash 因为 a+b=c ,所以 lena.lenb 至少要有一个等于 lenc 或 lenc-1  .所以枚举 lenc,每次检验一下可不可行. 但每次都暴力检验肯定超时,这里把字符串hash 一下,根据 hash值 快速检验. 记一下模板: const int mod = 1e9+7; ll Hash[N], p[N

CodeForces - 589A(二分+贪心)

题目链接:http://codeforces.com/problemset/problem/589/F 题目大意:一位美食家进入宴会厅,厨师为客人提供了n道菜.美食家知道时间表:每个菜肴都将供应. 对于第i道菜肴,他知道时间ai和bi的两个整数时刻(从宴会开始的几秒钟内) - ai为该菜端出来的时间,bi为该菜端走的时间(ai <BI).例如,如果ai = 10且bi = 11,那么第i个菜肴可在一秒钟内进食. 菜肴数量非常大,所以只要菜肴可以吃(即,在大厅里),它就无法用完. 美食家想要尝试每

codeforces 589A Email Aliases(map)

Description Polycarp has quite recently learned about email aliases. Of course, he used to suspect that the case of the letters doesn't matter in email addresses. He also learned that a popular mail server in Berland bmail.com ignores dots (character

CodeForces (字符串从字母a开始删除k个字母)

You are given a string s consisting of n lowercase Latin letters. Polycarp wants to remove exactly k characters (k≤n) from the string s. Polycarp uses the following algorithm k times: if there is at least one letter 'a', remove the leftmost occurrenc

SZU1

CodeForces 518A 字符串进位.. #include <iostream> #include <string> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #include <algorithm> #include <stack> #include <queue> #include &l

codeforces 825F F. String Compression dp+kmp找字符串的最小循环节

/** 题目:F. String Compression 链接:http://codeforces.com/problemset/problem/825/F 题意:压缩字符串后求最小长度. 思路: dp[i]表示前i个字符需要的最小次数. dp[i] = min(dp[j]+w(j+1,i)); (0<=j<i); [j+1,i]如果存在循环节(自身不算),那么取最小的循环节x.w = digit((i-j)/x)+x; 否则w = i-j+1; 求一个区间最小循环节: 证明:http://w

Codeforces 176B (线性DP+字符串)

题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28214 题目大意:源串有如下变形:每次将串切为两半,位置颠倒形成新串.问经过K次变形后,与目标串相同的变形方案数.mod 1000000007. 解题思路: 奇葩的字符串DP.照着别人的题解写的,解释不出原理是什么. 首先统计出经过1次变形,就能和目标串相同的中间产物串(包含源串)的个数cnt.len表示源串长度,那么len-cnt就表示和目标串不同的个数. 用