一:
/*
请编写程序统计每种不同的个位数字出现的次数。例如:给定 N=100311,则有 2 个 0,3 个 1,和 1 个 3。*/
#include<iostream>
#include<string.h>
using namespace std;
int main()
{
string num;
int i,j,n,a[10]={0},k;
cin>>num;
n=num.length();
for(i=0;i<n;i++)
{
k=num[i]-'0';
a[k]+=1;
}
for(j=0;j<10;j++)
{
if(a[j]!=0)
{
cout<<j<<":"<<a[j]<<endl;
}
}
return 0;
}
1.1:求string型长度
- 用string的成员方法length()获取字符串长度,
length()比较直观,表示的就是该字符串的长度。
str.length ()
(2)用string的成员方法size()获取字符串长度
size()表示的是字符串这个容器中的元素个数。如果使用过std::vector之类的容器的话,可以把字符串看做是一个vector<char>(这里只是举的例,并不能等价),字符就是这个容器的元素类型。那么size()表示的就是这个向量(容器)中字符的个数。
str.size ()
(3)用strlen获取字符串长度
strlen同样也可以用于c++的字符串。但是需要用c-str()将c++字符串转换为char *类型。
len = str.length ();
1.2: k=num[i]-'0';
num[i]为字符型,减去一个字符‘0’可得对应的整数
二:
#include<bits/stdc++.h>
using namespace std;
long long gbs(long long a,long long b) //求公倍数
{
return b==0?a:gbs(b,a%b);
}
int main()
{
long long a[101],b[101],t,fz=0,fm=1;
int n,i;
cin>>n;
for(i=0;i<n;i++)
{
scanf("%lld/%lld",&a[i],&b[i]);
fm=fm*b[i]/gbs(fm,b[i]); //求出分母总和
}
for(i=0;i<n;i++)
fz+=(fm/b[i])*a[i]; //求出分子总和
t=gbs(fabs(fz),fm);
fz/=t;
fm/=t;
if(fz%fm==0)
cout<<fz/fm;
else if(fz>fm)
cout<<fz/fm<<" "<<fz%fm<<"/"<<fm;
else
cout<<fz<<"/"<<fm;
return 0;
}
2.1:万能头文件
#include<bits/stdc++.h>
2.2:求公倍数
long long gbs(long long a,long long b)
{
return b==0?a:gbs(b,a%b);
}
三:
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long n;
int i,j,couts,maxs=0,num,temp;
cin>>n;
for(i=2;i<=sqrt(n);i++)
{
couts=0;
j=i;
temp=n;
while(temp%j==0)
{
couts++;
temp/=j;
j++;
}
if(couts>maxs)
{
num=i;
maxs=couts;
}
}
if(maxs)
{
cout<<maxs<<endl;
cout<<num;
for(i=1;i<maxs;i++)
cout<<"*"<<num+i;
}
else
{
cout<<1<<endl;
cout<<n;
}
}
1.1:质因子最大为sqrt(n)
1.2:质因子求余为0
1.3:考虑n为素数的情况
四:
#include <iostream>
#include <map>
using namespace std;
int main()
{
string a, b;
map<char, int> mp; //建立char与int之间的map
getline(cin, a); //获取字符串
getline(cin, b);
for (int i = 0; i < b.length(); i++)
{
mp[b[i]] = 1; //建立下标为b[i]的数组,并赋值为1
}
for (int i = 0; i < a.length(); i++)
{
if (!mp[a[i]]) cout << a[i]; //数组a中存在b的不输出
}
return 0;
}
4.1
getline()的使用详解:
头文件:#include <string>
istream& getline (输出流(如cin) , 字符串(str) , 结束符(char) );
作用:此函数会一次读取多个字符(包括空白字符)。遇到指定的结束符为止
结束符,在不设置的情况下系统默认该字符为'\n',也就是回车换行符(遇到回车停止读入)。
例:getline(cin,line,'#');
cin.getline()的使用详解
cin.getline(字符指针(char*),字符个数N(int),结束符(char));
作用:此函数会一次读取多个字符(包括空白字符)。它以指定的地址为存放第一个读取的字符的位置,依次向后存放读取的字符,直到读满N-1个,或者遇到指定的结束符为止。若不指定结束符,则默认结束符为'\n'。
例:cin.getline(a, 10);//第10位存放字符串结束符'\0'
4.2
map的使用详解:
头文件:#include <map>
map<typename1,typename2> mp;
作用:a[key]=val,只不过数组元素的下标是任意一种类型,而且数组的元素的值也是任意一种类型。
注:map会以键从小到大自动排序,就是通过'a','b','c'的顺序来排这三个键值对,这是由于集合内部是通过红黑树来实现的,在建立映射的时候会自动实现从小到大的排序。
例:map<char,int> mp;
mp['a']=10;
cout<<mp[‘a’];
输出:10
五:
#include <stdio.h>
#include <string.h>
int love[100010]; //存储ID号空间
int main()
{
int n; //有几个朋友圈
int k; //每个朋友圈中有几个人
int m; //待查询人数
int id; //id号码
int newid; //待查询的id号码
int i,j; //用于循环和数组下标
int flag=0; //用来判断输出结果是否是因为太帅没有朋友
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&k);
for(j=0;j<k;j++)
{
scanf("%d",&id);
if(k == 1)break;//只有自己的朋友圈排出
love[id] = 1; //每个人ID肯定都是不同的,所以让朋友圈中已知的都值为1
}
}
scanf("%d",&m);
for(i=0;i<m;i++)
{
scanf("%d",&newid);
if(!love[newid])//这里要注意判断条件为非真为假,非假为真的特性,已存在时
{ //就无需在输出,利用这一特点,我们只要把事先没有存在的输出即可
if(++flag > 1) printf(" ");
printf("%05d",newid);
love[newid] = 1;
}
}
if(flag == 0) printf("No one is handsome");
printf("\n");
return 0;
}
六:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int sushu(int n)
{
int i;
if (n == 1)
{
return 0;
}
for (i = 2; i <= sqrt(n); i++)
{
if (n%i == 0)
{
return 0;
}
}
return 1;
}
int main()
{
int a, b, c;
scanf("%d", &a);
for (b = 0; b < a; b++)
{
scanf("%d", &c);
if (sushu(c))
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
七:L1-046 整除光棍
#include <stdio.h>
int main(){
int x;
scanf("%d",&x);
int s = 1;
int c = 1;
while(s<x){
s = s*10+1;
c ++;
}
int y;
do{
y = s%x;
printf("%d",s/x);
if(y == 0){
break;
}
s = y*10+1;
c ++;
}while(y!=0);
printf(" %d\n",c);
return 0;
}
需要模拟除法运算 ( 除法是从高位到低位 除了能整除的情况外 必然会有余数 从小打大我们的习惯都是向低位借一位 也就是在余数后添一个0 或者可以说是让这个余数乘以10 而这个题目的情况是在余数后添1 就相当于余数乘以10再加1
八:L1-050 倒数第N个字符串
#include<iostream>
#include<cmath>
using namespace std;
int main(){
int L, N;
cin >> L >> N;
double M = pow((double)26, (double)L) - N;
int m = (int)M; //相减得到从0开始的序号
char ch[6]; //定义长度为6的字符数组
int i = 0; //存储L长度的字符
while (L--) { ch[i++] = 'a' + m % 26; m /= 26; } //数组从前往后存储从从右到左的字符
for (int j = i - 1; j >= 0; j--) cout << ch[j]; //逆序输出
return 0;
}
九:L1-058 6翻了
/*从左到右扫描输入的句子:如果句子中有超过 3 个连续的 6,则将这串连续的 6 替换成 9;但如果有超过 9 个连续的 6,则将这串连续的 6 替换成 27。其他内容不受影响,原样输出。*/
#include<iostream>
#include<cmath>
using namespace std;
string s;
int main()
{
getline(cin,s);
for(int i=0;i<s.length();i++)
{
int cn=0;//清0方便下次循环
while(s[i]=='6')//遇到6就一直循环看有几个6
{
cn++;
i++;//找的同时顺带还跳过了所有的6,cout<<s[i];就不会输出6了
}
if(cn<=3)
{
for(int j=0;j<cn;j++)
cout<<"6";
}
else if(cn>3&&cn<=9)
cout<<"9";
else if(cn>9)
cout<<"27";
cout<<s[i];
}
return 0;
}
十:L1-070
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str,a="chi1 huo3 guo1";
int i,j,k=0,key=0,x,y=0;
getline(cin,str);
for(i=0;str!=".";i++)
{
if(str.find(a) != string::npos)
{
key++;
if(k==0)
{
y=i;
k++;
}
}
getline(cin,str);
}
if(key>0)
printf("%d\n%d %d",i,y+1,key);
else
printf("%d\n-_-#",i);
return 0;
}
find()函数类:
- find()
(1)size_t find (const string& str, size_t pos = 0) const; //查找对象--string类对象
(2)size_t find (const char* s, size_t pos = 0) const; //查找对象--字符串
(3)size_t find (const char* s, size_t pos, size_t n) const;//查找对象--字符串的前n个字符
(4)size_t find (char c, size_t pos = 0) const; //查找对象--字符
结果: 找到 -- 返回 第一个字符的索引 没找到--返回 string::npos
实例:
string str1, str2;
char c;
str1.find(str2);//从串str1中查找时str2,返回str2中首个字符在str1中的地址
str1.find(str2,5);//从str1的第5个字符开始查找str2
str1.find(c);//在str1中查找字符并返回第一个查找到的地址
str1.find("str2",2 , 2);//从str1中的第二个字符开始查找str2的前两个字符
2. find_first_of()
函数原型:int find_first_of(char c, int start = 0);
这个用法和①中str1.find(str2)相似,都是返回str2中首个字符在str1中的地址。
但是要特别注意,没有找到时返回值是-1.
3.find_last_of()
函数原型:int find_last_of(char c);
未找到时返回-1。
4.find_not_first_of()
函数原型:size_type find_first_not_of( char ch, size_type index = 0 );
在字符串中查找第一个与str中的字符都不匹配的字符,返回它的位置。搜索从index开始。如果没找到就返回string::nops。
5.find_not_last_of()
函数原型:size_type find_last_not_of( char ch, size_type index = 0 );
在字符串中查找最后一个与str中的字符都不匹配的字符,返回它的位置。搜索从index开始。如果没找到就返回string::nops。
实例:
string snake1("cobra");
int where = snake1.find_first_of("hark");
/*返回3 因为 "hark"中 各一个字符 在 snake1--cobra 中第一次出现的是 字符'r'(3为 cobra 中'r'的索引)*/
//同理:
int where = snake1.find_last_of("hark");
/*返回4 因为 "hark"中 各一个字符 在 snake1--cobra 中最后一次出现的是 字符'a'(3为 cobra 中'r'的索引)*/
2345的作用是查找 字符串中 任一个字符 满足的查找条件
十一:学生成绩排序(结构体数组排序)
/*
对某班学生成绩排序。从键盘依次输入某班学生的姓名和成绩(一个班级人数最多不超过50人)并保存,然后分别按学生成绩由高到低顺序输出学生姓名和成绩,成绩相同时,则按输入次序排序。
*/
#include<bits/stdc++.h>
using namespace std;
int main()
{
struct xs //构建结构体,使分数和姓名在一起
{
string name;
int score;
} s[100];
xs temp;
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>s[i].name;
cin>>s[i].score;
}
for(int i=0;i<n-1;i++)
{
for(int j=0;j<n-1-i;j++)
{
if(s[j].score<s[j+1].score)
{
temp=s[j];
s[j]=s[j+1];
s[j+1]=temp;
}
}
}
for(int i=0;i<n;i++)
{
cout<<setw(15)<<s[i].name;
printf("%5d\n",s[i].score);
}
return 0;
}
十二:求最小公倍数或最大公约数
#include<stdio.h>
int gcd(int a,int b){
if(b==0) return a; //若b为0,则最大公约数为a
else return gcd(b,a%b); //否则,则改为求b与a%b的最大公约数
}
int main(){
int a,b;
while(scanf("%d%d",&a,&b)!=EOF){ //输入两个正整数
printf("%d\n",gcd(a,b)); //输入所求的最大公约数
}
return 0;
}
#include<stdio.h>
int gcd(int a,int b){ //求最大公约数
return b!=0 ? gcd(b,a%b):a;
}
int main(){
int a,b;
while(scanf("%d%d",&a,&b)!=EOF){
printf("%d\n",a*b/gcd(a,b)); //输出两数乘积与最大公约数的商,商即为最小公倍数
}
return 0;
}十三:旋转魔方阵
/*
输入一个自然数N(N属于2到15),要求输出如下的魔方阵,即边长为NN,元素取值为1至NN,1在左上角,呈顺时针方向依次放置各元素。
N=3时:
1 2 3
8 9 4
7 6 5
*/
#include<bits/stdc++.h>
using namespace std;
int main()
{
int **a;
int n,i,j,k=1,x,y;
cin>>n;
a=new int *[n]; //建立动态数组
for(i=0;i<n;i++)
{
a[i]=new int [n];
}
for(i=0;k<=n*n;i++)
{
x=i;
y=i;
while(y<n-1-i)
a[x][y++]=k++;
while(x<n-1-i)
a[x++][y]=k++;
while(y>i)
a[x][y--]=k++;
while(x>i)
a[x--][y]=k++;
if(x==n-1-x&&y==n-1-y) //n为奇数为中央的空位赋值
a[x][y]=k++;
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("%5d",a[i][j]);
}
cout<<endl;
}
for(i=0;i<n;i++) //删除动态数组
{
delete [] a[i];
}
delete [] a;
return 0;
}
十四:科学计数法
/*
科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [+-][1-9].[0-9]+E[+-][0-9]+,即数字的整数部分只有 1 位,小数部分至少有 1 位,该数字及其指数部分的正负号即使对正数也必定明确给出。
*/
#include<iostream>
#include<string>
using namespace std;
int main()
{
string n;
cin >> n;
int n_len = n.length();
string s = n.substr(1, n.find('E')-1); //s是E之前的字符串
string s2 = n.substr(n.find('E')+1, n_len); //s2是E之后的字符串
int n_s2 = stoi(s2); //输出正常数字
//负号
if (n[0] == '-')
cout << '-';
// E<0,只要在小数点前加0
if (n_s2 < 0) {
cout << "0.";
for (int i = 1; i < -n_s2; i++)
cout << 0;
for (int i = 0; i < s.length(); i++) {
if (s[i] != '.') {
cout << s[i];
}
}
}
//E>=0时,要移动小数点,在补0
else {
cout << s[0];
int cnt, j;
for (j = 2, cnt = 0; j < s.length() && cnt < n_s2; j++, cnt++)
cout << s[j];
//j == s.length 说明s中的数字已经输出完,后面位数用0补
if (j == s.length()) {
for (int k = 0; k < n_s2 - cnt; k++)
cout << 0;
}
//否则,小数点移动到这里,继续输出s剩下的数字
else {
cout << '.';
cout << s.substr(j, s.length());
}
}
return 0;
}
substr(开始位置,结束位置):
主要功能:复制子字符串,要求从指定位置开始
例子:
string str = "101010";
string a = str.substr( 1, 3);
a=”010”;
stoi(字符串,起始位置,n进制)
主要功能: 将 n(默认为十进制) 进制的字符串转化为十进制
头文件:#include <string>
示例: stoi(str, 0, 2); //将字符串 str 从 0 位置开始到末尾的 2 进制转换为十进制
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str = "1010";
int a = stoi(str, 0, 2);
cout << a << endl;
return 0;
}
输出结果:10
十五:旧键盘
/*
旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现。现在给出应该输入的一段文字、以及实际被输入的文字,请你列出肯定坏掉的那些键。按照发现顺序,在一行中输出坏掉的键。其中英文字母只输出大写,每个坏键只输出一次。
*/
#include <iostream>
#include <cctype>
using namespace std;
int main()
{
string s1, s2, ans;
cin >> s1 >> s2;
for (int i = 0; i < s1.length(); i++)
if (s2.find(s1[i]) == string::npos && ans.find(toupper(s1[i])) == string::npos)
ans += toupper(s1[i]);
cout << ans;
return 0;
}
toupper():
主要功能:int toupper(int c) 把小写字母转换为大写字母。
isupper();
主要功能:int isupper(int c) 检查所传的字符是否是大写字母。
如果 c 是一个大写字母,则该函数返回非零值(true),否则返回 0(false)
十六:汉诺塔
/*
大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,任何时候,在小圆盘上都不能摆放大圆盘,且在三根柱子之间只能移动一个圆盘。如果三个柱分别命名为A,B,C,A柱子上有64片黄金圆盘,问应该如何操作才能实现该任务?
*/
#include<bits/stdc++.h>
using namespace std;
int loop(int n,char a1,char a2,char a3) //递归算法,将n个盘从a1柱到a3柱
{
if(n>=1)
{
loop(n-1,a1,a3,a2); //将n-1个盘移到a2柱
printf("%c->%c\n",a1,a3); //将第n个移到a3
loop(n-1,a2,a1,a3); //再把a2柱上的n-1个盘移到a3柱
}
return 0;
}
int main()
{
int n;
cin>>n;
loop(n,'A','B','C');
return 0;
}
十七:走台阶
/*
有个人刚刚看完电影 《第39 级台阶》离开电影院时,他数了数礼堂前的台阶数,恰好是39 级! 站在台阶前,他想到一个问题: 如果我每一步只能迈上 1 个或 2 个台阶,先迈左脚,然后左右交替,最后一步迈右脚,也就是说一共要走偶数步, 那么, 上完 39 级台阶有多少种不同的上法呢?要求用程序实现输入n级台阶,计算出有多少种不同的上法。
*/
#include<bits/stdc++.h>
using namespace std;
int sum=0; //走法总数
int loop(int c,int s) //剩余c为台阶数,s为走过的步数
{
if(c<0)return 0;
if(c==0) //c==0时走完台阶
{
if(s%2==0) //步数为偶数时方法成立
{
sum++;
}
return 0;
}
loop(c-1,s+1); //迈一个台阶
loop(c-2,s+1); //迈两个台阶
}
int main()
{
int c;
cin>>c;
loop(c,0);
cout<<sum;
return 0;
}
十八: 在霍格沃茨找零钱
/*
如果你是哈利·波特迷,你会知道魔法世界有它自己的货币系统 —— 就如海格告诉哈利的:“十七个银西可(Sickle)兑一个加隆(Galleon),二十九个纳特(Knut)兑一个西可,很容易。”现在,给定哈利应付的价钱P和他实付的钱A,你的任务是写一个程序来计算他应该被找的零钱。
在一行中用与输入同样的格式输出哈利应该被找的零钱。如果他没带够钱,那么输出的应该是负数
*/
#include <iostream>
#include <cstdio>
#include <stdlib.h>
using namespace std;
int main()
{
int PG,PS,PK,AG,AS,AK;
scanf("%d.%d.%d %d.%d.%d",&PG,&PS,&PK,&AG,&AS,&AK);
int P = PK+PS*29+PG*29*17;
int A = AK+AS*29+AG*29*17;
bool B = true;
if(P > A)
B = false;
int temp = abs(A-P);
int CG = temp/(29*17);
int CS = (temp%(29*17))/29;
int CK = (temp%(29*17))%29;
if(!B)
printf("-%d.%d.%d", CG, CS, CK);
else
printf("%d.%d.%d", CG, CS, CK);
return 0;
}
十九:字符统计
/*请编写程序,找出一段给定文字中出现最频繁的那个英文字母。*/
#include<bits/stdc++.h>
using namespace std;
int main()
{
int s[27]={0};
int maxs=0,len;
string str;
getline(cin,str);
len=str.length();
for(int i=0;i<len;i++)
{
str[i]=tolower(str[i]);
if(islower(str[i]))
s[str[i]-'a']++;
}
for(int i=1;i<27;i++)
{
if(s[maxs]<s[i])
maxs=i;
}
cout<<(char)(maxs+'a')<<" "<<s[maxs];
return 0;
}
tolower():
主要功能:int tolower(int c) 把大写字母转换为小写字母。
islower();
主要功能:int islower(int c) 检查所传的字符是否是小写字母。
如果 c 是一个小写字母,则该函数返回非零值(true),否则返回 0(false)
二十:天梯赛的善良
/*
输入在第一行中给出一个正整数 N(≤2×104),即参赛学生的总数。随后一行给出 N 个不超过 106 的正整数,是参赛学生的能力值。
第一行输出所有参赛学生的最小能力值,以及具有这个能力值的学生人数。第二行输出所有参赛学生的最大能力值,以及具有这个能力值的学生人数。同行数字间以 1 个空格分隔。
*/
#include<bits/stdc++.h>
using namespace std;
int main() {
int n;
cin>>n;
int a[n];
for(int i=0; i<n; i++)
cin>>a[i];
sort(a,a+n); //排序
int min=a[0],max=a[n-1];
int mini=0,maxi=0;
for(int i=0; i<n; i++) {
if(a[i]==max)
maxi++;
if(a[i]==min)
mini++;
}
cout<<min<<" "<<mini<<endl;
cout<<max<<" "<<maxi<<endl;
return 0;
}
sort有三个参数,第三个参数不写时,默认按照升序排列。
第一个参数:数组名,也就是数组首地址
第二个参数:一般形式为“数组名+n”,其中n是你想从数组首地址开始,排序的数字元素的个数
注意:1.sort的前两个参数相当于是确定一个你想要排序的元素的地址所在的区间,
从数学角度来讲,是一个左闭右开区间,所以第二个参数不是所要排序的最后一个元素的地址,
而是进行排序的最后一个元素的后一个元素的地址
2.记得加上头文件: #include<algorithm>