目录
1. 组队竞赛
1.2 思路
1.3代码实现
2.排序子序列
2.1 思路
2.2 代码实现
3. 数组中出现次数超过一半的数字
3.1 思路
3.2 代码实现
4. 计算糖果
4.1 思路
4.2 代码实现
5. 进制转换
5.1 思路
5.2 代码实现
6. 删除公共字符
6.1 思路
6.2 代码实现
7. 倒置字符串
7.1 思路
7.2 代码实现
8. 字符串中找出连续最长的数字串
8.1 思路
8.2 代码实现
牛牛举办了一次编程比赛,参加比赛的有3*n个选手,每个选手都有一个水平值a_i.现在要将这些选手进行组队,一共组成n个队伍,即每个队伍3人.牛牛发现队伍的水平值等于该队伍队员中第二高水平值。
例如:
一个队伍三个队员的水平值分别是3,3,3.那么队伍的水平值是3
一个队伍三个队员的水平值分别是3,2,3.那么队伍的水平值是3
一个队伍三个队员的水平值分别是1,5,2.那么队伍的水平值是2
为了让比赛更有看点,牛牛想安排队伍使所有队伍的水平值总和最大。
如样例所示:
如果牛牛把6个队员划分到两个队伍
如果方案为:
team1:{1,2,5}, team2:{5,5,8}, 这时候水平值总和为7.
而如果方案为:
team1:{2,5,8}, team2:{1,5,5}, 这时候水平值总和为10.
没有比总和为10更大的方案,所以输出10.
输入描述:
输入的第一行为一个正整数n(1 ≤ n ≤ 10^5) 第二行包括3*n个整数a_i(1 ≤ a_i ≤ 10^9),表示每个参赛选手的水平值.
输出描述:
输出一个整数表示所有队伍的水平值总和最大值.
这就是一个贪心的策略,想让总和最大那我直接从大到小排好每次取第二个,取n次就好了。
#include
#include
#include
using namespace std;
int main(){
vector v;
long long n,ret = 0;
cin >> n;
int a = 3*n;
long long temp = 0;
while(a--)
{
cin >> temp;
v.push_back(temp);
}
sort(v.begin(),v.end(),greater());
for(int i = 1;i<=(2*n-1);i+=2)
{
ret+=v[i];
}
cout << ret << endl;
}
牛牛定义排序子序列为一个数组中一段连续的子序列,并且这段子序列是非递增或者非递减排序的。牛牛有一个长度为n的整数数组A,他现在有一个任务是把数组A分为若干段排序子序列,牛牛想知道他最少可以把这个数组分为几段排序子序列.
如样例所示,牛牛可以把数组A划分为[1,2,3]和[2,2,1]两个排序子序列,至少需要划分为2个排序子序列,所以输出2
输入描述:
输入的第一行为一个正整数n(1 ≤ n ≤ 10^5) 第二行包括n个整数A_i(1 ≤ A_i ≤ 10^9),表示数组A的每个数字。
输出描述:
输出一个整数表示牛牛可以将A最少划分为多少段排序子序列
1.v[j] > v[j + 1]就是一个非递减排序的 碰见不满足v[j] >= v[j + 1] count++ ;
2.v[j] < v[j + 1]就是一个非递增排序的 碰见不满足v[j] <= v[j + 1] count++ ;
3.v[j] == v[j + 1] 没有起或者伏往下走 j++;
#include
#include
using namespace std;
int main(){
int n;
cin>>n;
vector v;
//防止越界
v.reserve(n + 1);
//总的子序列的个数
int count = 0;
for(int i = 0;i < n;++i)
{
cin >> v[i];
}
int j = 0;
while(j < n)
{
if(v[j] < v[j + 1])
{
while(v[j] <= v[j + 1])
{
j++;
}
count++;
j++;
}
else if(v[j] > v[j + 1])
{
while(v[j] >= v[j + 1])
{
j++;
}
count++;
j++;
}
else
{
j++;
}
}
cout << count <
给一个长度为 n 的数组,数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
例如输入一个长度为9的数组[1,2,3,2,2,2,5,4,2]。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。
数据范围:n \le 50000n≤50000,数组中元素的值 0 \le val \le 100000≤val≤10000
要求:空间复杂度:O(1)O(1),时间复杂度 O(n)O(n)
保证数组输入非空,且保证有解
1. 拿到这个题首先我想到就是排序然后 加一个计数器count 遍历数组前后俩相等 count++ 出现不相等里面 count 置零 如果 count 大于总元素个数的一半就return,还要加一点边界判断。
2. 之后发现了其实如果大于一半的话肯定那个数字必然在中间,大于总元素个数的一半 。其实直接把中间那个元素 return 都可以,做到这发现其实你一直用的是 sort(); 也就是快排时间复杂度还是有的能不能再降一降。
3. 我们用哈希映射的思想用unordered_map来做,遍历一遍数组把值出现的次数存到map中,然后再遍历一遍找出来最多的。
// class Solution {
// public:
// int MoreThanHalfNum_Solution(vector numbers) {
// //有快排时间复杂度 O(N log N)
// sort(numbers.begin(),numbers.end());
// int count = 0;
// int ret = 0;
// for(int i = 0; i < numbers.size(); i++)
// {
// if(numbers[i] == numbers[i + 1])
// {
// ++count;
// if(count >= (numbers.size() >> 1))
// {
// ret = numbers[i];
// }
// }
// else
// {
// count = 0;
// }
// }
// if(numbers.size() == 1)
// {
// return numbers[0];
// }
// return ret;
// }
// };
// class Solution {
// public:
// int MoreThanHalfNum_Solution(vector numbers)
// {
// //既然他的长度大于数组的一半那说明中间必然是所求数字
// sort(numbers.begin(),numbers.end());
// int middle = numbers[numbers.size() >> 1];
// int count = 0;
// for(int i = 0;i < numbers.size();++i)
// {
// if(numbers[i] == middle)
// {
// count++;
// }
// }
// return (count > numbers.size() >> 1) ? middle : 0;
// }
// };
// class Solution {
// public:
// int MoreThanHalfNum_Solution(vector numbers)
// {
// sort(numbers.begin(),numbers.end());
// return numbers[numbers.size() >> 1];
// }
// };
class Solution {
public:
int MoreThanHalfNum_Solution(vector numbers) {
unordered_map mp;
for (auto & val : numbers)
{
mp[val]++;
}
for (auto & val : numbers)
{
if (mp[val] > numbers.size() >> 1)
{
return val;
}
}
return 0;
}
};
A,B,C三个人是好朋友,每个人手里都有一些糖果,我们不知道他们每个人手上具体有多少个糖果,但是我们知道以下的信息:
A - B, B - C, A + B, B + C. 这四个数值.每个字母代表每个人所拥有的糖果数.
现在需要通过这四个数值计算出每个人手里有多少个糖果,即A,B,C。这里保证最多只有一组整数A,B,C满足所有题设条件。
输入描述:
输入为一行,一共4个整数,分别为A - B,B - C,A + B,B + C,用空格隔开。 范围均在-30到30之间(闭区间)。
输出描述:
输出为一行,如果存在满足的整数A,B,C则按顺序输出A,B,C,用空格隔开,行末无空格。 如果不存在这样的整数A,B,C,则输出No
这个就是一个翻译的过程,还有就是对结果的逆向判断一下看看是否有解的问题。
#include
#include
using namespace std;
int main()
{
vector v;
v.reserve(4);
int temp = 0;
int a = 0, b = 0, c = 0;
for(int i = 0;i < 4;i++)
{
cin >> v[i];
}
a = (v[0] + v[2]) >> 1;
b = (v[1] + v[3]) >> 1;
c = (v[3] - v[1]) >> 1;
//A - B,B - C,A + B,B + C 来逆推一下
if ((a - b) == v[0] && (b - c) == v[1] && (a + b) == v[2] && (b + c) == v[3])
{
cout << a << " " << b << " " << c;
}
else
{
cout << "No";
}
}
给定一个十进制数M,以及需要转换的进制数N。将十进制数M转化为N进制数
输入描述:
输入为一行,M(32位整数)、N(2 ≤ N ≤ 16),以空格隔开。
输出描述:
为每个测试实例输出转换后的数,每个输出占一行。如果N大于9,则对应的数字规则参考16进制(比如,10用A表示,等等)
1. 先有一个string类对象 s 保存结果 辗转相除的结果不只有数字还有 A 到 F 字母 maptable 对象 存放
2. 判断是否为负数是的话就在最后加上 - 就好了
3. 你辗转相除的结果就是反过来的也就是逆序的 在最后拼接的时候就是 将 s 放在后面
#include
#include
using namespace std;
int main()
{
string s = "",maptable = "0123456789ABCDEF";
int m = 0;
int n = 0;
cin >> m >> n;
if(m == 0)
{
s = "0";
}
while(m)
{
if(m < 0)
{
m = -m;
cout << "-";
}
s = maptable[m % n] + s;
m /= n;
}
cout << s << endl;
}
输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。例如,输入”They are students.”和”aeiou”,则删除之后的第一个字符串变成”Thy r stdnts.”
每个测试输入包含2个字符串
输出删除后的字符串
1. 这个题的第一思路就是遍历字符串s1 然后从 s2 第一个开始找找完一次删一个 然后指针++ 移动到 s2 的第二个,这样的话时间复杂度很高就是O( N ^ 2);
2. 可以用哈希映射的方式来处理;
3. 给一个hashtable 先遍历 s2 统计一下s2中字符出现的个数 给一个 string 类对象 ret 接受返回值,s1 映射过来如果等于0的话就说明这个字符没在 s2 中出现过直接拼接到 ret 上;
#include
#include
using namespace std;
int main(){
string s1, s2, ret;
getline(cin,s1);
getline(cin,s2);
int hashtabel[255] = { 0 };
for(int i = 0;i < s2.size();i++)
{
hashtabel[s2[i]]++;
}
for(int i = 0;i < s1.size();i++)
{
if(hashtabel[s1[i]] == 0)
{
ret += s1[i];
}
}
cout << ret << endl;
}
将一句话的单词进行倒置,标点不倒置。比如 I like beijing. 经过函数后变为:beijing. like I
每个测试输入包含1个测试用例: I like beijing. 输入用例长度不超过100
依次输出倒置之后的字符串,以空格分割
这个一个利用stack特性的一种巧解的思路
#include
#include
using namespace std;
int main()
{
string s1;
string s2;
cin >> s1;
while(cin >> s2)
{
s1 = s2 + " " + s1;
}
cout << s1 <
读入一个字符串str,输出字符串str中的连续最长的数字串
个测试输入包含1个测试用例,一个字符串str,长度不超过255。
在一行内输出str中里连续最长的数字串。
1. 实例化两个string对象 cur 和 ret 一个是当前的字符串,一个是要返回的字符串;
2. 判断是否是数字是的话拼接cur 一次次更新直到找到最长的数字串;
#include
#include
using namespace std;
int main()
{
string s;
string ret,cur;
getline(cin,s);
for(int i = 0;i <= s.size();i++)
{
if(s[i]>='0' && s[i]<='9')
{
cur += s[i];
}
else
{
if(ret.size() < cur.size())
{
ret = cur;
}
else
{
cur.clear();
}
}
}
cout << ret;
return 0;
}