1.分苹果(差分数组)
小朋友排成一排,老师给他们分苹果。
小朋友从左到右标号1…N。有M个老师,每次第i个老师会给第Li个到第Ri个,一共Ri-Li+1个小朋友每人发Ci个苹果。
最后老师想知道每个小朋友有多少苹果。
输入
第一行两个整数N、M,表示小朋友个数和老师个数。
接下来M行,每行三个整数Li、Ri、Ci,意义如题目表述。
数据规模和约定
100%的数据,N、M≤100 000,1≤Li≤Ri≤N,0≤Ci≤100。
输出
一行N个数,第i个数表示第i个小朋友手上的水果。
样例输入
5 3
1 2 1
2 3 2
2 5 3
样例输出
1 6 5 3 3
解题思路:
1.用二维数组时导致时间超时
2.看了别人的题解,需要用到差分知识
差分知识点
#include<iostream>
using namespace std;
int main()
{
int n, m;
cin >> n >> m;
int apple[100005] = { 0 };
int l, r, c;
while (m--)
{
cin >> l >> r >> c;
apple[l] += c;
apple[r + 1] -= c;
}
for (int i = 1; i <= n; i++)
{
apple[i] = apple[i] + apple[i - 1];
cout << apple[i] << " ";
}
return 0;
}
2.分数统计
题目描述
给定一个百分制成绩T,将其划分为如下五个等级之一:
90100为A,8089为B,7079为C,6069为D,0~59为E
现有若干百分制成绩(成绩个数不超过1000个),请你统计五个等级段的人数,并找出人数最多的那个等级段,按照从大到小的顺序输出该段中所有人成绩(保证人数最多的等级只有一个)。
输入
第一行是成绩的个数 n
第二行是学生的成绩,若干0~100的正整数,用空格隔开
输出
第一行为5个正整数,分别表示A,B,C,D,E五个等级段的人数
第二行一个正整数,表示人数最多的等级段中人数
接下来一行若干个用空格隔开的正整数,表示人数最多的那个等级中所有人的分数,按从大到小的顺序输出。
样例输入
10
100 80 85 77 55 61 82 90 71 60
样例输出
2 3 2 2 1
3
85 82 80
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
//动态申请一维数组
int* grad = new int[n];
//输入成绩
for (int i = 0; i < n; i++)
{
cin >> grad[i];
}
//先对成绩进行排序
sort(grad, grad + n);
//用一个二维数组来记录每个区间段的位置
int tem[5][2];
tem[0][0] = 0;//0-59开始的位置
for (int i = 0; i<n-1; i++)//从最低分开始
{
if (grad[i]<=59&&grad[i+1]>=60)
{
tem[0][1] = i+1;//0-59的结尾位置
tem[1][0] = i+1;//60-69的开始位置
}
else if (grad[i]<=69&&grad[i+1]>=70)
{
tem[1][1] = i+1;//60-69的结尾位置
tem[2][0] = i+1;//70-79的开始位置
}
else if(grad[i] <= 79 && grad[i + 1] >= 80)
{
tem[2][1] = i + 1;//70-79的结尾位置
tem[3][0] = i + 1;//80-89的开始位置
}
else if (grad[i] <= 89 && grad[i + 1] >= 90)
{
tem[3][1] = i + 1;//80-89的结尾位置
tem[4][0] = i + 1;//90-100开始位置
tem[4][1] = n ;//90-100的结尾位置
}
}
int max=0;
int flag = 0;//标记找到最大值的位置
for (int i = 4; i >= 0; i--)
{
if ((tem[i][1] - tem[i][0]) > max)
{
max = tem[i][1] - tem[i][0];
flag = i;
}
cout << (tem[i][1] - tem[i][0]) << " ";
}
cout << endl << max << endl;
for (int i = tem[flag][1]-1; i >= tem[flag][0]; i--)
{
cout << grad[i] << " ";
}
delete[]grad;
return 0;
}
3.蓝桥杯算法提高VIP-大数加法
题目描述
输入两个正整数a,b,输出a+b的值。
输入
两行,第一行a,第二行b。a和b的长度均小于1000位。
输出
一行,a+b的值。
样例输入
4
2
样例输出
6
解题思路:大数计算用字符串来处理,用两个字符串来储存数据,分别从两个字符串的最后一位开始转化为整型数据在于进位值相加(最开始的进位值为0),模10结果在转化为字符串存到一个结果字符串当中,并记录是否有进位,
关键点1:数据的转化,字符串转化为整型:(int)string[i]-(int)'0’另一种函数stoi(str.c_str())这是针对字符数组的而不是字符串数组
关键点2:有四种情况的相加方式,两个字符串都有数据,一个有一个没有(种),两个都没有(但还有进位)
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int main()
{
string a, b;
cin >> a >> b;
//获取两个字符串的长度
int lena = a.size();
int lenb = b.size();
int n;//获取最长的字符串的长度
if (lena > lenb)
n = lena;
else
{
n = lenb;
}
string tem = "";//结果字符串存储相加后的值
int jinwei = 0;//表时是否产生进位
for (int i = 0; i <= n; i++)//需要=n,因为要判断最后结果是否比最长的还要长一位
{
//两个字符串都最后一位开始
lena--;
lenb--;
int tema, temb;//临时存储两个字符串一个字符转化的整型值
if (lena >= 0)//判断字符串a是否提取完
tema = (int) a[lena]-(int)'0';//字符串转化为整型的方法
if (lenb >= 0)
temb = (int) b[lenb]-(int)'0';
if (lena >= 0 && lenb >= 0)//表示两个字符串都提取数据
{
tem = tem + to_string((tema + temb + jinwei) % 10);//把相加值mod10存入结果字符串当中
if ((tema + temb+jinwei)>=10)//判断是否进位
jinwei = 1;
else
{
jinwei = 0;
}
}
else if(lena>=0&&lenb<0)//只有a字符有数据,b字符串提取完了
{
tem = tem + to_string((tema + jinwei) % 10);
if ((tema + jinwei) >= 10)
jinwei = 1;
else
{
jinwei = 0;
}
}
else if (lena < 0 && lenb >= 0)//只有b字符有数据,a字符串提取完了
{
tem = tem + to_string((temb + jinwei) % 10);
if ((temb + jinwei) >= 10)
jinwei = 1;
else
{
jinwei = 0;
}
}
else if(jinwei>0)//两个字符串都提取完了,最后还要看看是否还有进位
{
tem = tem + to_string(jinwei);
}
}
for (int i = tem.size()-1; i >= 0; i--)//从结果字符串最后一位开始输出
cout << tem[i];
return 0;
}
4.蓝桥杯算法提高VIP-寻找三位数
题目描述
将1,2,…,9共9个数分成三组,分别组成三个三位数,且使这三个三位数构成
1:2:3的比例,试求出所有满足条件的三个三位数。
例如:三个三位数192,384,576满足以上条件。
输入
无输入文件
输出
输出每行有三个数,为满足题设三位数。各行为满足要求的不同解。
样例输入
无
样例输出
无
**首先分析一下取值范围:有三个值假设abc:def:ghi=1:2:3;并且abcdefghi分别代表一个数字保证不重复。(懂我说的意思吧) 我们只用确定abc这个数的范围就可以知道其他两个数的对应值,然后暴力求解即可。首先abc最小肯定是123,ghi最大是987;那么abc最大就是ghi/3=329;然后我们枚举123到329之间的值(范围也不大),对应def的值就是2abc,ghi的值就是3abc;每一趟遍历对应abc、def、ghi的值都能确定,我们可以吧abc、def、ghi写入到一个指定的字符串数组中,然后排序,根据字典序和我们最开始设置的"123456789"这个字符串比较,相同的话说明1到9每个数字都用到了,反之不合题意;思路就是这。**思路来源https://blog.dotcpp.com/a/10732
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int main()
{
string tem = "";//临时储存一组结果,并用来进行比较
for (int i = 123; i <= 987 / 3; i++)//i从最小的123,到最大329进行遍历
{
tem += to_string(i) + to_string(i * 2) + to_string(i * 3);//把这一组数据放在一个字符串中
//对字符串进行排序,(直接插入排序),
for (int i = 1; i < tem.size(); i++)
{
char e = tem[i];
int j;
for (j = i - 1; j >= 0 && e < tem[j]; j--)
{
tem[j + 1] = tem[j];
}
tem[j + 1] = e;
}
long long int num = 123456789;//用来进行对比,用来判断是否有重复
long long int shuju = stoi(tem.c_str());//把tem转化为int型进行比较
if (shuju == num)//没有重复
{
cout << i << " " << i * 2 << " " << i * 3 << endl;
}
tem = "";//清空字符串进行下一个对比
}
return 0;
}
5.题目 1536: 蓝桥杯算法提高VIP-最长单词
题目描述
编写一个函数,输入一行字符,将此字符串中最长的单词输出。
输入仅一行,多个单词,每个单词间用一个空格隔开。单词仅由小写字母组成。所有单词的长度和不超过100000。如有多个最长单词,输出最先出现的。
输入
无
输出
无
样例输入
I am a student
样例输出
student
解题思路:
1.读取屏幕输入的字符串
2.一个一个的访问字符串,并且读取的字符储存在一个临时字符串中
3.遇到空格就把临时字符串输入到vector中
4.因为最后一次没有有空格,最后还有在进行一次把临时字符串输入到vector中
5.在vector中找最大的位数
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main()
{
string tem;
getline(cin, tem);//从屏幕上读取字符,含空格。如果直接用cin是不能读进空格的
vector<string> str;//用来储存以空格分割的字符串
string cunchu="";//储存分割的字符串
//一个一个访问字符串
for (int i = 0; i < tem.size(); i++)
{
if (tem[i] != ' ')//逐渐积累单词
cunchu += tem[i];
else
{
str.push_back(cunchu);//把词放进vector中
cunchu = "";
}
}
str.push_back(cunchu);//把最后一个字符串也放进vector
//找最大值
int max = str[0].size();//假设第一个为最大值
int pos = 0;//记录最大值的位置
for (int i = 1; i < str.size(); i++)
{
if (str[i].size() > max)
{
max = str[i].size();
pos = i;//记录最大的位置
}
}
cout << str[pos];
return 0;
}