12月25日

145 阅读4分钟

1.单词分析

题意

小蓝正在学习一门神奇的语言,这门语言中的单词都是由小写英文字母组 成,有些单词很长,远远超过正常英文单词的长度。小蓝学了很长时间也记不住一些单词,他准备不再完全记忆这些单词,而是根据单词中哪个字母出现得最多来分辨单词。

现在,请你帮助小蓝,给了一个单词后,帮助他找到出现最多的字母和这 个字母出现的次数。

输入描述

输入一行包含一个单词,单词只由小写英文字母组成。

对于所有的评测用例,输入的单词长度不超过 1000。

输出描述

输出两行,第一行包含一个英文字母,表示单词中出现得最多的字母是哪个。如果有多个字母出现的次数相等,输出字典序最小的那个。

第二行包含一个整数,表示出现得最多的那个字母在单词中出现的次数。

image.png

代码

#include <iostream>a
#include <cstring>
#include <string.h>
#include <string>
#define pragma GCC optimize(2)
#define F(i,a,b) for(int i = a; i < b; i++)
using namespace std;
/*
    1.定义字符串s,整型数组a(下标映射字母,数组元素值表示有多少个), 字符数组ch(存a~z)
      整型变量max=0(字母出现最多的), index(存最多字母的下标),字符变量p='a'
    2. 输入字符串s
    3. 遍历字符串s,do:
		  a. 将字符串s的每个字符映射到数组a
              即a[s[i] - 'a']++
	4. for循环将a~z字母存到字符数组ch中
	5. 遍历数组a, do:
			a.如果a[i]不等于0
				a-1.如果max小于a[i]
                       a-2. 就将a[i]赋值给max
                       a-3. 将i赋值给index
	6. 输出ch[index]和max
*/
int a[30];
char ch[26];
bool cmp(string a, string b) {
    return a < b;
}
int main() {
    ios::sync_with_stdio(false);
    string s;
    cin >> s;
    int max = 0, index;
    for(int i = 0; s[i]; i++) {
        a[s[i] - 'a']++;
    }
    char p = 'a';
    for(int i = 0; i < 26; i++, p++)
        ch[i] = p;
    F(i,0,30) {
        if(a[i]) {
            if(max < a[i]) {
                max = a[i];
                index = i;
            }
        }
    }
    cout << ch[index] << endl;
    cout << max;
    return 0;
}

2. 成绩统计

题意

小蓝给学生们组织了一场考试,卷面总分为 100 分,每个学生的得分都是一个 0 到 100 的整数。

如果得分至少是 60 分,则称为及格。如果得分至少为 85 分,则称为优秀。

请计算及格率和优秀率,用百分数表示,百分号前的部分四舍五入保留整 数。

输入输出

image.png

image.png

代码

#include <iostream>
#include <math.h>
#define pragma GCC optimize(2)
#define F(i,a,b) for(int i = a; i < b; i++)
using namespace std;
int n,jg = 0,yx = 0;
int jgl, yxl;
const int N = 10100;
int a[N];
/*
    及格率:及格人数 / 总人数,四舍五入保留整数
    优秀率:优秀人数(>=85分) / 总人数
    
    1.定义整型变量 n(人数),jg=0(及格人数),yx=0(优秀人数),jgl,yxl
      数组a
	2. 输入n
	3. for i=0 to n-1 do: 输入a[i]
	4. for i=0 to n-1 do:
			a. 如果分数大于等于60
				a-1.就及格人数加1
				a-2.如果分数大于等于85
                  a-2-1.优秀的人数加1
			b.否则,跳过
	5. 用round函数求jgl和yxl
	6. 输出jgl和yxl
*/
int main() {
    ios::sync_with_stdio(false);
    cin >> n;
    F(i,0,n) cin >> a[i];
    F(i,0,n) {
        if(a[i] >= 60) {
            jg++;
            if(a[i] >= 85)
                yx++;
        } else continue;
    }
//    cout << jg << " " << yx;
    jgl = round((100*((double)jg/(double)n)));
    yxl = round((100*((double)yx/(double)n)));
    printf("%d%%\n%d%%",jgl,yxl);
    return 0;
}

3.排序

全逆乱序冒泡排序次数为 N*(N-1)/2

题意

小蓝最近学习了一些排序算法,其中冒泡排序让他印象深刻。

在冒泡排序中,每次只能交换相邻的两个元素。

小蓝发现,如果对一个字符串中的字符排序,只允许交换相邻的两个字符, 则在所有可能的排序方案中,冒泡排序的总交换次数是最少的。

例如,对于字符串 lan 排序,只需要 1 次交换。对于字符串 qiao 排序,总共需要 4 次交换。

小蓝找到了很多字符串试图排序,他恰巧碰到一个字符串,需要 100次交 换,可是他忘了吧这个字符串记下来,现在找不到了。

请帮助小蓝找一个只包含小写英文字母且没有字母重复出现的字符串,对 该串的字符排序,正好需要 100 次交换。如果可能找到多个,请告诉小蓝最短的那个。如果最短的仍然有多个,请告诉小蓝字典序最小的那个。

代码

#include <iostream>
#include <algorithm>
#include <math.h>
#include <sstream>
#include <string>
#include <string.h>
#include <cstring>
#include <vector>
#define F(i,a,b) for(int i = a; i < b; i++)
#define LL long long
#pragma GCC optimize(2)
using namespace std;
string s;
/*
    lan     1次交换
    qiao    4次交换

    全逆乱序冒泡排序次数为 N*(N-1)/2
    15 * 14 / 2 = 105
    14 * 13 / 2 = 91
    100次交换至少需要15个字母
    abcde fghij klmno
    105-5, 少交换5次
    把第六位的数往前交换5次,排在首位
*/
int bubbleSort(string &s) {
    int n = s.size();
    int cnt = 0;
    F(i,0,n-1) {
        F(j,0,n-i-1) {
            if(s[j] > s[j+1]) {
                swap(s[j], s[j+1]);
                cnt++;
            }
        }
    }
    return cnt;
}
int main() {
    ios::sync_with_stdio(false);
    s = "jonmlkihgfedcba";
//    cout << bubbleSort(s); //105
    cout << s;
    return 0;
}

4. 合数个数

题意

一个数如果除了 11 和自己还有其他约数,则称为一个合数。例如:1, 2, 31,2,3 不是合数,4, 64,6 是合数。

请问从 1 到 2020 一共有多少个合数。

代码

#include <iostream>
#include <math.h>
#define pragma GCC optimize(2)
#define F(i,a,b) for(int i = a; i < b; i++)
using namespace std;
/*
	1. 定义整型变量cnt = 0
	2. for循环遍历1~2020之间的数,do:
	        a. 如果i不是质数且i不等于1,就cnt加1
	3. 输出cnt
*/
int isPrime(int n) {
    if(n == 1)
        return 0;
    for(int i = 2; i*i <= n; i++) {
        if(n % i == 0)
            return 0;
    }
    return 1;
}
int main() {
    ios::sync_with_stdio(false);
    int cnt = 0;
    F(i, 1, 2021) {
        if(isPrime(i)==0 && i != 1) {
//            cout << i << " ";
            cnt++;
        }
    }
    cout << cnt;
    return 0;
}

4.美丽的2

题意

小蓝特别喜欢 22,今年是公元 2020 年,他特别高兴。 他很好奇,在公元 1 年到公元 2020 年(包含)中,有多少个年份的数位中包含数字 2?

代码

#include <iostream>
#include <math.h>
#define pragma GCC optimize(2)
#define F(i,a,b) for(int i = a; i < b; i++)
using namespace std;
/*
	1.定义整型变量cnt=0(计数都要初始化变量为0,如果是累乘器就初始化为1)
	2. 定义contain2函数(int n)
		 a.定义整型变量flag=0(一开始不包含2)
		 b. 只要n不等于0,do:
			  b-1. 如果个位数等于2,flag就标记为1
			  b-2. 砍掉个位(也就是说不断看个位数是否等于2)
		c. 返回flag
	3. for i=1 to 2020, do:
	        a.如果i这个数包含2,就cnt加1
	4. 输出cnt
*/
int contain2(int n) {
    //22
    int cnt = 0;
    int flag = 0;
    while(n) {
        if(n % 10 == 2)
            flag = 1;
        n /= 10;
    }
    return flag;
}
int main() {
    ios::sync_with_stdio(false);
    int cnt = 0;
//    cout << contain2(9);
    F(i,2, 2021) {
        if(contain2(i))
            cnt++;
    }
    cout << cnt;
    return 0;
}

5. 单词重排

题意

将 LANQIAO 中的字母重新排列,可以得到不同的单词,如 LANQIAOAAILNOQ 等,注意这 7 个字母都要被用上,单词不一定有具体的英文意义。

请问,总共能排列如多少个不同的单词?

1.dfs代码

#include <iostream>
#define F(i,a,b) for(int i = a; i < b; i++)
#define pragma GCC optimize(2)
#define LL long long
using namespace std;
/*
    abc
    acb
    bac
    bca
    cab
    cba 6种  3!
    n个数的全排列 = n!, 如果有2个相同的数或字母,就除以2,n个相同的,就除以n
    
    1. 定义整型变量n=77个数排列),res=0,数组g,数组vis
    2. 定义dfs函数(int t)
			a. 如果t等于n+1(到达叶子结点,算一个全排列)
				a-1.res加1(结果累加)
				a-2.返回
			b. for i=1 to n(尝试每一种可能)
				b-1. 如果没访问过
						b-1-1. 标记访问
						b-1-2. 将i赋值给数组g[t]
						b-1-3. 递归下一层
						b-1-4. 回溯
	3.调用dfs函数(1),从1开始
	4. 因为有2个A,所以将res除等于2
	5.输出res
    
*/
const int N = 10000;
int n = 7, res = 0;
int g[N];
int vis[N] = {0};
void dfs(int level) {
    if(level == n+1) {
//        for(int j = 1; j <= n; j++)
//            cout << g[j] <<  " ";
//        cout << endl;
            res++;
        return;
    }
    for(int i = 1; i <= n; i++) {
        if(vis[i] == false) {
            vis[i] = 1;
            g[level] = i;
            dfs(level + 1);
            vis[i] = 0;
            g[level] = 0;
        }
    }
}
int main() {
    ios::sync_with_stdio(false);
    dfs(1);
    //因为有2个A,所以要除以2
    res /= 2;
    cout << res;
    return 0;
}

2.系统函数代码

#include <iostream>
#include <string>
#include <algorithm>
#define F(i,a,b) for(int i = a; i < b; i++)
#define pragma GCC optimize(2)
#define LL long long
using namespace std;
/*
	1. 定义字符串s="LANQIAO",整型变量res=1(一开始算一个全排列)
	2. 对字符串s进行排序
	3. 只要(下一个全排列(s.begin(),s.end())),do: res加1
	4. 输出res
*/

int main() {
	ios::sync_with_stdio(false);
	string s = "aabb";
	sort(s.begin(), s.end());
	int res = 1;
	//while(next_permutation(s.begin(),s.end()))
	while(next_permutation(s.begin(),s.end()))
		res++;
	cout << res;
	return 0;
}

6. 查找字符最大元素

题意

对于输入的每个字符串,查找其中的最大字母,在该字母后面插入字符串“(max)”

输入输出

输入数据包括多个测试实例,每个实例由一行长度不超过100的字符串组成,字符串仅由大小写字母及数字构成。
对于每个测试实例输出一行字符串,输出的结果是插入字符串“(max)”后的结果,如果存在多个最大的字母,就在每一个最大字母后面都插入"(max)"。

image.png

代码

#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#define F(i,a,b) for(int i = a; i < b; i++)
#define pragma GCC optimize(2)
using namespace std;
/*
	1.定义字符串s,定义字符变量max=s[0]
	2.循环输入s, do:
		a.遍历字符串s,do:
			a-1. 如果max小于s[i], 就将s[i]赋值给max(找到最大的字符)
		b.遍历字符串s,do:
			b-1. 如果当前字符不等于max,就输出当前字符
			b-2. 否则就先输出当前字符再输入(max)
		c. 换行
*/
string s;
int main()
{
	ios::sync_with_stdio(false);
	while(cin >> s) {
		char max = s[0];
		for(int i = 0; s[i]; i++) {
			if(max < s[i])
				max = s[i];
		}
		for(int i = 0; s[i]; i++) {
			if(s[i] != max)
				cout << s[i];
			else
				printf("%c(max)", s[i]);
		}
		cout << endl;
	}
	return 0;
}

7. 回文字符串

题意

回文串是从左到右或者从右到左读起来都一样的字符串,试编程判别一个字符串是否为回文串。是则输出Y,不是则输出N

image.png

代码

#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#define F(i,a,b) for(int i = a; i < b; i++)
#define pragma GCC optimize(2)
using namespace std;
	/*
	    回文串
	    1. 定义字符串s
	    2. 循环输入s, do:
				a.定义整型变量flag=1,len=字符串s的长度
				b. for循环,i从0指向中间,j从末尾指向中间,只要i小于等于中间,do:
					 b-1.如果s[i]不等于s[j],就将flag标记为0
				c. 如果flag等于1,输出'Y', 否则,输出'N'
	*/
string s;
int main()
{

    ios::sync_with_stdio(false);
	while(cin >> s) {
		int flag = 1;
		int len = s.size();
		for(int i = 0,j=len-1; i <= len/2; i++, j--) {
			if(s[i] != s[j]) {
				flag = 0;
			}
		}

		if(flag == 1)
			cout << "Y" << endl;
		else
			cout << "N" << endl;
	}
	return 0;
}

8.去掉空格

题意

读入一些字符串,将其中的空格去掉。

输入输出

用c语言字符风格来写

image.png

image.png

#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#define F(i,a,b) for(int i = a; i < b; i++)
#define pragma GCC optimize(2)
using namespace std;
	/*
       1.定义字符串s
       2.循环输入字符串s, do:
			a.遍历字符串s,do:
				a-1. 如果s[i]等于空格字符,就跳过
				a-2. 否则,输出s[i]
				a-3.换行
	*/
string s;
int main()
{

![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9d128b3925b7464093bf925c9cdb37d6~tplv-k3u1fbpfcp-watermark.image?)
    ios::sync_with_stdio(false);
	char s[500];
	while(gets(s) != NULL) {
		for(int i = 0; s[i]; i++) {
		if(s[i] == 32)
			continue;
		else
			cout << s[i];
		}
		cout << endl;
	}
	return 0;
}

用c++风格来写

#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#define F(i,a,b) for(int i = a; i < b; i++)
#define pragma GCC optimize(2)
using namespace std;
	/*
       1.定义字符串s
       2.循环输入字符串s, do:
			a.遍历字符串s,do:
				a-1. 如果s[i]等于空格字符,就跳过
				a-2. 否则,输出s[i]
				a-3.换行
	*/
string s;
int main()
{

    ios::sync_with_stdio(false);
    string s;
	while(getline(cin, s) != NULL) {
		for(int i = 0; s[i]; i++) {
		if(s[i] == ' ')
			continue;
		else
			cout << s[i];
		}
		cout << endl;
	}
	return 0;
}

9.字符串正反连接

题意

所给字符串正序和反序连接,形成新串并输出

image.png

代码

#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#define F(i,a,b) for(int i = a; i < b; i++)
#define pragma GCC optimize(2)
using namespace std;
	/*
       1.定义字符串s
       2.输入字符串s
       3.输出字符串s
       4.for循环,i指向字符串的末尾,让i指到0为止,重复做
			a.输出每个字符
	*/
string s;
int main()
{

	ios::sync_with_stdio(false);
    char a[500];
	gets(a);
	printf("%s", a);
	for(int i = strlen(a)-1; i >= 0; i--) {
		putchar(a[i]);
	}
	return 0;
}

10. 求矩阵两对角线上的元素之和

题意

求矩阵的两对角线上的元素之和

输入输出

image.png image.png

代码

#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#define F(i,a,b) for(int i = a; i < b; i++)
#define pragma GCC optimize(2)
using namespace std;
	/*
       1 2 3
       4 5 6    => 1+5+9+3+7 = 25
       7 8 9
            一行一列+二行二列+三行三列 => i == j(左上-右下)
            一行三列+三行一列 =>0+2==n-1&&2+0==n-1 =>i+j == n-1
       1. 定义二维数组a,整型变量n,sum = 0
       2. 输入n
       3. for i=0 to n-1, do:
			for j=0 to n-1, do:
				 a.输入a[i][j]
				 b.如果i等于j或i+j等于n-1,就将a[i][j]放到累加器sum里
		4. 输出sum
	*/
const int N = 10;
int a[N][N];
int main()
{

	ios::sync_with_stdio(false);
    int n, sum = 0;
	cin >> n;
	for(int i = 0; i < n; i++) {
	    for(int j = 0; j < n; j++) {
	        cin >> a[i][j];
	        if(i == j)
				sum += a[i][j];
	    }
	}

	cout << sum;
	return 0;
}

11.统计字母个数

题意

给定一段文章,请输出每个字母出现的次数

输入输出

只有一组输入数据,文件少于1000行。在文章中除最后一个字符外,只有大小写字母、空格和换行符,没有另外的标点、数字。该文章以’#’结尾。
输出格式为“C A”,C为’a’..’z’中的字母,A为出现次数,C和A之间空一格image.png

代码

#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#define F(i,a,b) for(int i = a; i < b; i++)
#define LL long long
using namespace std;
/*
   1. 定义字符串s,整型数组alp用来存字母数量,字符数组p
   2. for循环将a`z之间的字符存入字符数组p中
   3.  死循环,重复做:
            a. 输入字符串s
            b. 定义整型变量flag=0
            c. 遍历字符串s,do:
				c-1. 如果s[i]等于'#'
					c-1-1. 将flag标记为1
					c-1-2. 退出内层循环
				c-2. 没遇到'#',就让alp相对应的字母数量加1
				c-3. 如果s[i]是大写,也让alp相对应的字母数量加1
			d. 如果flag等于1,就退出外层循环
  4. 遍历alpha数组,do:
		a.输出每个字母p[i]和每个字母的数量alp[i]
*/
char s[1008600];
int alp[26] = {0};
char p[1000];
int main()
{
	for(int i = 'a', j = 0; i <= 'z'; i++) {
		p[j++] = i;
	}
	while(1) {
//		getline(cin, s);
		gets(s);
		int flag = 0;
        for(int i = 0; i < strlen(s); i++) {
        	if(s[i] == '#') {
        		flag = 1;
        		break;
			}
			alp[s[i] - 'a']++;
			if(isupper(s[i]))
				alp[s[i] - 'A']++;
		}
		if(flag == 1)
				break;
	}
	for(int i = 0; i < 26; i++) {
			cout << p[i] << " " << alp[i] << endl;
	}
	return 0;
}