题目汇总
- HJ2 计算某字符出现次数
- HJ3 明明的随机数
- HJ4 字符串分隔
- HJ5 进制转换
- HJ6 质数因子
- HJ7 取近似值
- HJ8 合并表记录 哈希表
- HJ9 提取不重复的整数
- HJ10 字符个数统计
- HJ11 数字颠倒
- HJ12 字符串反转
- HJ13 句子逆序
- HJ14 字符串排序
- HJ15 求int型正整数在内存中存储时1的个数
- HJ16 购物单 dp0-1背包问题
- HJ17 坐标移动
HJ2 计算某字符出现次数
HJ3 明明的随机数
明明生成了NN个1到500之间的随机整数。请你删去其中重复的数字,即相同的数字只保留一个,把其余相同的数去掉,然后再把这些数从小到大排序,按照排好的顺序输出。
数据范围: 1≤n≤1000 1≤n≤1000 ,输入的数字大小满足 1≤val≤500 1≤val≤500
#include <iostream>
using namespace std;
//用数组下标来规范随机数序列
int Rank(int n) //有序数组的接口
{
int random_num;//输入随机数
//初始化一个数组,用于表示随机数集合中的元素(0-1000之间的随机整数)的有无情况
int a[1001]={0};
//连续输入n个随机整数
while(n--)
{
cin>>random_num;
//数组的下标等于输入的随机整数,下标对应的元素为1表示随机整数存在
a[random_num]=1;
}
//按照从小到大的顺序依次输出随机数集合所包含的随机整数
for (int i=0; i<1000; i++) {
if (a[i]==1)
{
cout<<i<<endl;
}
}
return 0;
}
int main()
{
int n;//输入随机数的个数
while(cin>>n)
{
Rank(n);
}
return 0;
}
HJ4 字符串分隔
•输入一个字符串,请按长度为8拆分每个输入字符串并进行输出;
•长度不是8整数倍的字符串请在后面补数字0,空字符串不处理。
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
while (cin>>str)//输入字符串,直到输完
{
//补0
int len = str.size();//字符串大小
if(len %8!=0)//如果整除
{
int count = 8-len%8;//算需要补足的0个数
str.append(count,'0');//补0
}
int newLen=str.size();
for (int i=0; i<newLen; i+=8)
{
cout<<str.substr(i,8)<<endl;
//字符串类的 substr 方法在循环内部被调用,有两个参数:i,它是子串的起始索引,8,它是子串的长度。该方法返回从索引 i 开始到索引 i+7 结束的子字符串(因为长度为 8)。
}
}
}
HJ5 进制转换
写出一个程序,接受一个十六进制的数,输出该数值的十进制表示。
数据范围:保证结果在 1≤n≤231−1 1≤n≤231−1
#include <iostream>
#include <string>
using namespace std;
//字符串自带与数值的转换函数
int main()
{
string str;
while(cin>>str)
{
cout<<stoi(str,0,16)<<endl;
//stoi() 函数是 C++ 标准库的一部分,用于将字符串转换为整数。
//在此特定示例中,str 是一个正在转换为整数的字符串变量。 stoi() 的第二个参数中的 0 指定要处理的字符串中第一个字符的索引。 在这种情况下,这意味着将处理整个字符串。
//stoi() 的第三个参数指定字符串中使用的数字系统的基数。 在本例中,基数为 16,这表明该字符串代表一个十六进制数
}
}
HJ6 质数因子
功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
long n;
cin>>n;
for (long i=2; i<=sqrt(n)&&i<=n; i++) //从小到大的质因子,质因子不能超过它的开方
{
while (n%i==0)//可以整除
{
cout<<i<<" ";
n/=i;//除掉质因子
}
}
if(n-1)//自己本身就是质数
cout<<n<<" ";
return 0;
}
这个还有递归的方法,待整理
HJ7 取近似值
#include <iostream>
using namespace std;
int main()
{
float x;
cin>>x;
cout<<(int)(x+0.5)<<endl;//int 向下舍入到最近的整数
return 0;
}
HJ8 合并表记录 哈希表
数据表记录包含表索引index和数值value(int范围的正整数),请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照index值升序进行输出。
#include <iostream>
#include <map>
using namespace std;
int main()
{
int n;
cin>>n;//输入键值对的个数
map<int,int> m;
//使用map容器,自带键值对数据结构 程序首先声明一个整数变量 n 来存储要输入的键值对的数量,并声明一个 map<int, int> 变量 m 来存储键值对
map<int, int>::iterator it;
//map类型的迭代器 它还声明了一个类型为 map<int, int>::iterator 的迭代器 it 来迭代地图的元素
for (int i=0; i<n; i++) {//从标准输入中读取 n 个键值对
int a,b;
cin>>a>>b;//每行输入一个键值对
it=m.find(a);//查找键a是否存在 调用地图对象上的 find() 方法来检查地图中是否已经存在该键
if (it!=m.end()) {//如果存在,对键相同的单元的值部分进行求和
m[a]=it->second+b;
}else{
m[a]=b; //如果键不存在,它只是将键值对插入到映射中。
}
}
for (it=m.begin(); it!=m.end(); it++) {
cout<<it->first<<" "<<it->second<<endl;
}
}
这是一个C++程序,读取一个数字n,表示要输入的键值对的个数,然后从标准输入中读取n个键值对。
它使用C++标准库中的map容器来存储键值对,并对出现多次的键的值进行求和运算。
最后,它将生成的键值对输出到标准输出。
映射map容器是一种关联容器,它根据键按照排序顺序存储键值对。它允许基于键高效地搜索、插入和删除元素。
地图容器内部使用红黑树来维护元素的顺序。
程序首先声明一个整数变量 n 来存储要输入的键值对的数量,并声明一个 map<int, int> 变量 m 来存储键值对。
它还声明了一个类型为 map<int, int>::iterator 的迭代器 it 来迭代地图的元素。 然后程序进入一个循环,从标准输入中读取 n 个键值对。
对于每个键值对,它首先通过调用地图对象上的 find() 方法来检查地图中是否已经存在该键。 如果键存在,它将值添加到映射中键的现有值。 如果键不存在,它只是将键值对插入到映射中。
最后,程序使用 begin() 和 end() 方法遍历映射的元素,并按照键的顺序将每个键值对输出到标准输出。
总的来说,这个程序演示了使用 C++ 中的地图容器来有效地存储和操作键值对。
HJ9 提取不重复的整数
输入一个 int 型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。
保证输入的整数最后一位不是 0 。
#include <iostream>
using namespace std;
int main()
{
int num;
cin>>num;
int a[10]={0};//初始化
while (num>0) {
int t= num%10; //取尾数
num=num/10;//更新剩下的数
if(a[t]==0)//用数组标记是否重复出现 当尾数和下标相同
//为0就是没有出现,不重复,则输出,否则不输出
{
cout<<t;//输出t,输出就是反序输出的
a[t]=1;//赋值为1
}
}
}
其中把数字的各个位的数提取出来,因此输出之后已经是反序,因为输出的位数肯定是0-9的数字,标记数组a都赋值为零,当一个数字输出之后赋值为1,在if中添加标记一项,为0即没出现,不重复,则输出,否则不进行输出。
HJ10 字符个数统计
编写一个函数,计算字符串中含有的不同字符的个数。字符在 ASCII 码范围内( 0~127 ,包括 0 和 127 ),换行表示结束符,不算在字符里。不在范围内的不作统计。多个相同的字符只计算一次
例如,对于字符串 abaca 而言,有 a、b、c 三种不同的字符,因此输出 3 。
输入一行没有空格的字符串。
#include <iostream>
#include <set>
using namespace std;
int main()
{
string text;//存放输入的字符串
getline(cin,text);//获取输入的一行字符串
set<char> s;//使用set容器
for (int i=0; i<text.length();i++ )
{
s.insert(text[i]);//将text中的字符逐个添加到set容器中
// 对于输入字符串中的每个字符,程序使用集合容器的 insert() 函数将字符添加到集合中。insert() 函数确保只将唯一字符添加到集合中。
}
cout<<s.size()<<endl;
}
HJ11 数字颠倒
输入一个整数,将这个整数以字符串的形式逆序输出
程序不考虑负数的情况,若数字含有0,则逆序形式也含有0,如输入为100,则输出为001
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
int n;
cin>>n;
string s=to_string (n);//将数字转化成为字符串
reverse(s.begin(), s.end());//倒序
cout<<s<<endl;
return 0;
}
HJ12 字符串反转
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
string s;
cin>> s;
reverse(s.begin(), s.end());
cout<<s;
return 0;
}
HJ13 句子逆序
将一个英文语句以单词为单位逆序排放。例如“I am a boy”,逆序排放后为“boy a am I”
所有单词之间用一个空格隔开,语句中除了英文字母外,不再包含其他字符
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
int main()
{
string s;
string ans;
while(cin>>s)
{
ans=s+" "+ans;
}
cout<<ans<<endl;
return 0;
}
HJ14 字符串排序
#include <any>
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
vector<string> q;
int n;
//冒泡排序
int main()
{
cin>>n;
string s;
//输入n个字符串
for (int i=0; i<n; i++) {
cin>>s;
q.push_back(s);
}
for (int i=0; i<n; i++) {
for (int j=1; j<n; j++) {
if (q[j]<q[j-1]) {
swap(q[j], q[j-1]);
}
}
}
for (int i=0; i<n; i++) {
cout<<q[i]<<endl;
}
return 0;
}
HJ15 求int型正整数在内存中存储时1的个数
输入一个 int 型的正整数,计算出该 int 型数据在内存中存储时 1 的个数。
数据范围:保证在 32 位整型数字范围内
输入描述:
输入一个整数(int类型)
输出描述:
这个数转换成2进制后,输出1的个数
它使用“bitset”库来计算用户输入的整数的二进制表示形式中 1 的数量
“bitset”是一个库,它通过将二进制数表示为位序列来提供一种使用二进制数的便捷方法。 “bitset”库的“count”函数返回在 bitset 的二进制表示中设置为 1 的位数。 在这种情况下,程序创建了一个大小为 32 的位集(这是大多数现代系统上 int 的大小),并使用二进制表示形式“n”对其进行了初始化。 然后,它计算 bitset 中 1 的个数,这给出了“n”的二进制表示中 1 的个数。
#include <iostream>
#include <bitset> //看到二进制就要想到bitset
using namespace std;
int main() {
int n;
cin>>n;
bitset<32> b(n);
cout<<b.count();
}
该程序声明了一个整数变量“n”用于存储用户输入,并使用“cin”函数从用户那里读取一个整数。 该程序声明了另一个整型变量“m”并将其初始化为 0。该变量将用于计算“n”的二进制表示中 1 的个数。 程序进入一个“while”循环,只要“n”不为零,该循环就会继续。 在循环的每次迭代中,程序将“n”除以 2 的余数(即“n”的最后一个二进制数字)添加到“m”。 如果“n”的最后一个二进制数字是 1,那么这将增加“n”的二进制表示中 1 的计数。 然后程序将“n”除以 2,有效地将“n”的所有二进制数字向右移动一位。 这准备在循环的下一次迭代中将下一个二进制数字添加到“m”。 循环结束后,程序输出“m”的最终值,即“n”的二进制表示中 1 的个数。
#include <iostream>
using namespace std;
int main()
{
int n;
cin>>n;
int m=0;
while(n)
{
m+=n%2;
n/=2;
}
cout<<m;
}
HJ16 购物单 dp0-1背包问题
王强决定把年终奖用于购物,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
int N, m; // N 奖金 m 物品个数
cin >> N >> m;
N /= 10; // 由于所有的价格都是10的整倍数,所以可以均除10以简化运算复杂度
int price, priority, hasAttachments;
// 使用一个(m+1)X6的数组存储数据,m+1是根据物品编号,0作废;6考虑可能有附件的最多的情况
vector<vector<int>> data(m+1, vector<int>(6, 0));
for(int i = 1; i <= m; i++){
cin >> price >> priority >> hasAttachments;
// 主件
if(hasAttachments == 0){
data[i][0] = price/10;
data[i][1] = priority;
}
// 第一个附件
else if(data[hasAttachments][2] == 0){
data[hasAttachments][2] = price/10;
data[hasAttachments][3] = priority;
}
// 第二个附件
else {
data[hasAttachments][4] = price/10;
data[hasAttachments][5] = priority;
}
}
vector<vector<int>> dp(m+1, vector<int>(N+1, 0));
for(int i = 1; i < m+1; i++){
for(int j = 1; j < N+1; j++){
int pricePrime = data[i][0];
int priceAtta1 = data[i][2];
int priceAtta2 = data[i][4];
int priorPrime = data[i][1];
int priorAtta1 = data[i][3];
int priorAtta2 = data[i][5];
dp[i][j] = j >= pricePrime ? max(dp[i-1][j - pricePrime]
+ priorPrime * pricePrime,
dp[i-1][j]) : dp[i-1][j];
dp[i][j] = j >= (pricePrime + priceAtta1) ? max(dp[i-1][j - pricePrime - priceAtta1]
+ priorPrime * pricePrime
+ priorAtta1 * priceAtta1,
dp[i][j]) : dp[i][j];
dp[i][j] = j >= (pricePrime + priceAtta2) ? max(dp[i-1][j - pricePrime - priceAtta2]
+ priorPrime * pricePrime
+ priorAtta2 * priceAtta2,
dp[i][j]) : dp[i][j];
dp[i][j] = j >= (pricePrime + priceAtta1 + priceAtta2) ?
max(dp[i-1][j - pricePrime - priceAtta1 - priceAtta2]
+ priorPrime * pricePrime
+ priorAtta1 * priceAtta1
+ priorAtta2 * priceAtta2,
dp[i][j]) : dp[i][j];
}
}
cout << dp[m][N] * 10 <<endl;
return 0;
}
HJ17 坐标移动
#include <iostream>
#include <vector>
#include <string>
using namespace std;
//写坐标移动函数的接口
int Coodinate_Movement(string str)
{
int x=0,y=0;//初始化横纵坐标
int len=str.size();//获取字符串的总长度
vector<string>vec;//用一个向量来储存分割后的多个子字符串
//将字符串str按照“;”分割成多个子字符串substr,然后一次写入向量vec中
int sublen =0;//记录每个子字符串的长度
for (int i=0; i<len; i++) {
if (str[i]!=';') {
sublen++;
continue;
}
vec.push_back(str.substr(i-sublen,sublen));
sublen=0;//清空子字符串
}
//坐标移动,方向(左右上下)+大小(-99-99)
for (int i=0;i<vec.size(); i++) {
//确定坐标移动的大小,[-99-99]
int num=0;//横纵坐标移动的大小
//若字符串为三位有效位。那么第二和第三则是坐标移动的大小
if ((vec[i].size()==3)&&(vec[i][1]>='0')&&(vec[i][1]<='9')&&(vec[i][2]>='0')&&(vec[i][2]<='9'))
{
num=(vec[i][1]-'0')*10+(vec[i][2]-'0');
}
//如果字符串是两位有效位。那么第二位是坐标移动的大小
if ((vec[i].size()==2)&&(vec[i][1]>='0')&&(vec[i][1]<='9'))
{
num=(vec[i][1]-'0');
}
//如果字符串只有一位,则无坐标移动
if(vec[i].size()==1)
{
num=0;
}
//下面确定坐标移动的方向,左右上下
switch (vec[i][0]) {
case 'A': x-=num;
break;
case 'D': x+=num;
break;
case 'W': y+=num;
break;
case 'S': y-=num;
break;
default:
break;
}
}
cout<<x<<","<<y<<endl;
return 0;
}
int main()
{
string str;
while (cin>>str) {
Coodinate_Movement(str);
}
return 0;
}