1、判断数字
给定一个整数 n,请你统计其各位数字中 4 和 7 的出现次数。
如果 4 的出现次数加上 7 的出现次数恰好等于 4 或 7,则输出 YES,否则输出 NO。
例如,当 n=40047 时,4 出现了 2 次,7 出现了 1 次,2+1=3,既不是 4 也不是 7,因此,输出 NO;当 n=7747774 时,4 出现了 2 次,7 出现了 5 次,2+5=7,因此,输出 YES。
输入格式
一个整数 n。
输出格式
一行,YES 或者 NO。
数据范围
所有测试点满足 1≤n≤10^18。
输入样例1:
40047
输出样例1:
NO
输入样例2:
7747774
输出样例2:
YES
1、分析
简单模拟
2、代码
#include<iostream>
using namespace std;
typedef long long ll;
int main()
{
ll n;
int num_4 = 0,num_7 = 0;
cin >> n;
while(n)
{
if(n % 10 == 4) num_4 ++;
if(n % 10 == 7) num_7 ++;
n /= 10;
}
if(num_7 + num_4 == 4 || num_4 + num_7 == 7) cout << "YES";
else cout << "NO";
}
2、最长合法括号子序列
一个合法的括号序列满足以下条件:
序列()被认为是合法的。
如果序列X与Y是合法的,则XY也被认为是合法的。
如果序列X是合法的,则(X)也是合法的。
例如,(),()(),(())这些都是合法的。
现在,给定一个由 ( 和 ) 组成的字符串。
请你求出其中的最长合法括号子序列的长度。
注意,子序列不一定连续。
输入格式
共一行,一个由 ( 和 ) 组成的字符串。
输出格式
一个整数,表示最长合法括号子序列的长度。
数据范围
前五个测试点满足, 1≤输入字符串的长度≤10。
所有测试点满足,1≤输入字符串的长度≤10^6。
输入样例1:
(()))(
输出样例1:
4
输入样例2:
()()(()(((
输出样例2:
6
1、分析
利用栈进行处理
2、代码
#include<stack>
#include<iostream>
#include<cstring>
using namespace std;
stack<char> s;
int main()
{
string n;
cin >> n;
int res = 0;
for(int i = 0; i < n.size(); i ++)
{
if(n[i] == '(') s.push(n[i]);
else if(n[i] == ')')
{
if(!s.empty())
{
s.pop();
res += 2;
}
}
}
cout << res;
}
3、电话号码
一个电话销售员正在整理他的电话簿。
电话簿中记录了他的全部客户的电话号码。
一个客户可能有不止一个电话号码。
不同客户可能拥有完全相同的电话号码。
电话簿中一共包含 n 条记录。
每条记录都是首先包含一个字符串,表示客户的姓名,然后包含一个整数,表示本条记录包含的电话号码数量,最后是本条记录所包含的电话号码。
不同客户的姓名两两不同,所以如果两条记录包含的客户姓名相同,那么我们认为这都是记录的同一人的电话信息。
同一记录中可能包含相同的电话号码,不同记录中也可能包含相同的电话号码。
在进行整理时,应遵守如下原则:
如果一个客户拥有多条记录,则需要将这些记录进行合并,每人只保留一条记录,去记录他的全部有效号码。
如果一个客户记录的多个电话号码完全相同,则只保留一个作为有效号码,其余的全部视为无效号码。
如果一个客户记录的两个不同电话号码 a 和 b 满足 a 是 b 的后缀,则号码 a 视为无效号码。
请输出整理后的电话记录。
输入格式
第一行包含整数 n,表示记录数量。
接下来 n 行,每行描述一条记录,首先包含一个长度不超过 10 的由小写字母构成的非空字符串,表示客户姓名,然后包含一个不超过 10 的正整数,表示本条记录包含的号码数量,最后包含本条记录的所有号码,每个号码都是长度不超过 10 的由数字构成的非空字符串,可能包含前导 0。
输出格式
首先输出一个整数 m,表示完成整理后的记录数量。
接下来 m 行,每行输出一条记录信息,格式要求与输入一致。
同一行的数据之间用单个空格隔开。
记录的先后顺序随意,一条记录中的号码顺序随意。
数据范围
前三个测试点满足 1≤n≤4。
所有测试点满足 1≤n≤20。
输入样例1:
2
i 1 00123
m 1 00123
输出样例1:
2
m 1 00123
i 1 00123
输入样例2:
3
l 2 612 12
p 1 12
k 1 612
输出样例2:
3
k 1 612
p 1 12
l 1 612
输入样例3:
4
i 3 123 123 456
i 2 456 456
i 8 789 3 23 6 56 9 89 2
d 2 23 789
输出样例3:
2
d 2 23 789
i 4 789 123 2 456
1、分析
大模拟,用好stl工具进行适当处理即可
2、代码
#include<iostream>
#include<unordered_map>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
//key为用户名,value为用户的所有电话号码
unordered_map<string,vector<string> > mp;
int main()
{
int n;
cin >> n;
// 存储有效的用户数量
int resnum = 0;
for(int i = 0; i < n; i ++)
{
string name;
int num;
cin >> name >> num;
for(int i = 0; i < num; i ++)
{
string phone;
cin >> phone;
if(mp[name].size() == 0) resnum ++;
mp[name].push_back(phone);
}
}
cout << resnum << endl;
for(auto p : mp)
{
auto nums = p.second;
//先排序,用于后面unique去重
sort(nums.begin(),nums.end());
//由于前面排序了,所有重复的电话现在都相连,unique去除所有连续的重复电话
nums.erase(unique(nums.begin(),nums.end()),nums.end());
//判断所有不重复的电话,是否相互为后缀(感觉可以优化)
for(auto n = nums.begin(); n != nums.end(); n ++)
{
bool ifsub = false;
for(auto m = nums.begin(); m != nums.end() && !ifsub; m ++)
{
if((*n).length() <(*m).length())
{
bool issub = true;
for(int i = (*n).size() - 1,j = (*m).size() - 1; i >= 0; i --,j --)
{
if((*m)[j] != (*n)[i])
{
issub = false;
break;
}
}
if(issub)
{
ifsub = issub;
nums.erase(n);
n --;
}
}
}
}
cout << p.first << " " << nums.size();
for(int i = 0; i < nums.size(); i ++)
{
cout << " " << nums[i];
}
cout << endl;
}
}