C:(100分)(自己写的)
#include <stdio.h>
//---------这些为 复制过来的欧拉筛函数 的定义变量,详细见 https://blog.csdn.net/qq_61724978/article/details/123677077?spm=1001.2014.3001.5501
#define Max 100
bool num[Max] = { 0 };
int Prime[Max];
int b = 0;
int c = 0;
//---------
void GetAllPrime(int n) //欧拉筛 函数
{
num[1] = 1;
for (int i = 2; i <= n; i++)
{
if (!(num[i]))
{
Prime[++b] = i;
}
for (int j = 1; j <= b && i * Prime[j] <= n; j++)
{
num[i * Prime[j]] = 1;
if (i % Prime[j] == 0)
{
break;
}
}
}
}
int main()
{
char arr1[120] = { 0 }; //用于储存接收到的所有字母,第个字母放入下标为1的位置,如此类推
int arr2[26] = { 0 }; //用于统计字母的出现次数
//下标为1,表示字母 a
//下标为2,表示字母 b
//下标为........
//其中的元素为 (下标对应)字母的出现次数
int n = 0; //主要用于遍历 数组arr1 和 数组 arr2
//也可以表示输入了多少个字母
int max = 0; //储存 那个出现最多次的字母 的出现次数
int min = 100; //储存 那个出现最少次的字母 的出现次数
//注意一开始 min 要设置得大一些,如果设置为1的话 如果出现最少次数是2就寄了
//而且理论上讲 min 不等于 0
bool e = 1; //用于下面区分两个输出
//如果最后算出结果是Lucky Word,e会变成0,防止打印No Answer
//反之输出No Answer
char ch = ' ';
while (ch = getchar()) //无限读取 一个输入的字符,将这个字符储存到ch中
{
if (ch == '\n') //如果读取到换行符,就停止无限读取
{
break;
}
arr1[++n] = ch;
}
for (int i = 1; i <= n; i++)
{
arr2[(arr1[i] - 'a')]++; //统计 接收到的单词中 每个字母 的出现次数
//这里运用了ASCII表:https://baike.baidu.com/item/ASCII/309296?fr=aladdin(该连接为百度百科)
}
for (int i = 1; i <= 25; i++)
{
if (arr2[i] > max)
{
max = arr2[i];
}
if (arr2[i] < min && arr2[i] != 0)
{
min = arr2[i];
}
}
GetAllPrime(n); //欧拉筛,最后会得到一个 n以内的 所有素数的 数组Prime
//这题对 复制过来的欧拉筛的代码 进行了修改
//详细见:https://blog.csdn.net/qq_61724978/article/details/123677077?spm=1001.2014.3001.5501
for (int i = 1; i <= b; i++)
{
if (Prime[i] == max - min)
{
printf("Lucky Word\n%d", max - min);
e = 0;
}
}
if (e)
{
printf("No Answer\n0");
}
return 0;
}
C:看了其他大佬之后的修改版(100分)
发现我的思路居然跟有些大佬一样,开心。
修改如下:
1. 不需要欧拉筛,打表罗列出100以内的素数就好了
2. 优化了算法,去除了部分没用的循环和定义
#include <stdio.h>
const int Prime[25] = { 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97 };
int main()
{
int arr2[26] = { 0 }; //用于统计字母的出现次数
//下标为1,表示字母 a
//下标为2,表示字母 b
//下标为........
//其中的元素为 (下标对应)字母的出现次数
int n = 0; //主要用于遍历 数组arr1 和 数组 arr2
//也可以表示输入了多少个字母
int max = 0; //储存 那个出现最多次的字母 的出现次数
int min = 100; //储存 那个出现最少次的字母 的出现次数
//注意一开始 min 要设置得大一些,如果设置为1的话 如果出现最少次数是2就寄了
//而且理论上讲 min 不等于 0
bool e = 1; //用于下面区分两个输出
//如果最后算出结果是Lucky Word,e会变成0,防止打印No Answer
//反之输出No Answer
char ch = ' ';
while (ch = getchar()) //无限读取 一个输入的字符,将这个字符储存到ch中
{
if (ch == '\n') //如果读取到换行符,就停止无限读取
{
break;
}
arr2[(ch - 'a')]++; //统计 接收到的单词中 每个字母 的出现次数
}
for (int i = 1; i <= 25; i++)
{
if (arr2[i] > max)
{
max = arr2[i];
}
if (arr2[i] < min && arr2[i] != 0)
{
min = arr2[i];
}
}
for (int i = 0; i <= 24; i++)
{
if (Prime[i] == max - min)
{
printf("Lucky Word\n%d", max - min);
e = 0;
break;
}
}
if (e)
{
printf("No Answer\n0");
}
return 0;
}
C++:(100分)
与C的区别:
1. 储存输入的数组变成了string
2.采用了对 arr2数组 进行排序后再找最大小值,按理说应该减少循环次数更快的。。。。
#include <iostream>
#include <string>
#include <algorithm>
#include <list>
using namespace std;
const int Prime[25] = { 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97 };
int main()
{
int arr2[26] = { 0 }; //用于统计字母的出现次数
//下标为1,表示字母 a
//下标为2,表示字母 b
//下标为........
//其中的元素为 (下标对应)字母的出现次数
int max = 0; //储存 那个出现最多次的字母 的出现次数
int min = 100; //储存 那个出现最少次的字母 的出现次数
//注意一开始 min 要设置得大一些,如果设置为1的话 如果出现最少次数是2就寄了
//而且理论上讲 min 不等于 0
int i = 1; //用于查找最小值
bool e = 1;
string arr = "";
cin >> arr;
for (int i = 0; i <= arr.length(); i++)
{
arr2[(arr[i] - 'a')]++; //统计 接收到的单词中 每个字母 的出现次数
}
sort(arr2, arr2 + 26); //对数组排序,升序
max = arr2[25]; //因为是升序,所以下标为25的对应元素就是最大值
while (arr2[26 - i] != 0) //查找最小值
{
min = arr2[26 - i++];
}
for (int i = 0; i <= 24; i++)
{
if (Prime[i] == max - min)
{
printf("Lucky Word\n%d", max - min);
e = 0;
break;
}
}
if (e)
{
printf("No Answer\n0");
}
return 0;
}
python:(100分)
高级装逼版:
from collections import Counter
biao = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97];
a = Counter(input()).most_common(100)
max = (a[0])[1]
min = ((a)[len(a) - 1])[1]
if biao.count(max - min):
print(f"Lucky Word\n{max - min}")
else:
print(f"No Answer\n0")
拆分理解版:
from collections import Counter # 要使用 Counter 要引入该模块
biao = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]; # 100以内的素数打表
a = Counter(list(input())).most_common(100)
'''
这一行代码可以细分为 3 步,运行顺序由里到外
1. input() - 接受输入的内容,并返回 处理过的 输入的内容
2. Counter(input())
Counter() - 为强制转换,把 input() 返回的数据强制转换成 Counter计数器
这个 Counter计数器 会计算 input() 中所有的元素
例:
输入的内容为:1 2 3 4
经 input() 返回后会得到一个列表 ['1', ' ', '2', ' ', '3', ' ', '4']
强行转化为 Counter计数器 后得到 Counter({' ': 3, '1': 1, '2': 1, '3': 1, '4': 1}) (已自动排序)
其中表示:
空格有3个 字符'1'有1个 字符'2'有1个 字符'3'有1个 字符'4'有1个
Counter({' ': 3, '1': 1, '2': 1, '3': 1, '4': 1})
3. Counter(list(input())).most_common(100) (也可以看作 Counter.most_common(100) )
Counter.most_common() 是用来得到 Counter计数 结果中 出现次数最多的内容
它最后会返回一个 list列表,这个列表里面的每一个元素为元组,元组中有两个数据:出现次数最多的内容 和 出现的次数
()内的参数 是返回 元组的个数
以本题为例
如果为1,即返回 1 个 出现次数最多的内容 , 即返回 [(' ', 3)]
如果为2,即返回 2 个 出现次数最多的内容 , 即返回 [(' ', 3), ('1', 1)]
注意:()里面的值大于2, 里面的元组 会根据 从左到右 出现次数从多到少 的顺序 自动排序
这里()内 的 100 建议填大些,这里的目的是 得到 所有元素的出现次数
如果输入的是error,即最后统计Counter统计出来的只有3种 - r, e, o,哪怕这里()填了1000,也只会返回含有 3 个元组的列表
'''
max = ( a[0] ) [1]
'''
这一行代码可以细分为 2 步,运行顺序由里到外
1. a 是一个列表 里面有 一个或多个 自动排序后的 元组
经 自动排序 后知道 “第 1 个元组是表示出现次数最多的内容以及他的出现次数”
在 list列表 后 加上 [0] 来访问第一个内容,即 a[0],本题为: ('r', 3)
2. 由 1 得到 a[0] 会返回一个 元组,里面有 出现次数最多的内容 以及他的 出现次数
由 1 观察元组可以得知:
元组内的第 1 个数据为 出现次数最多的内容
元组内的第 2 个数据为 内容的出现次数
依照题目我们需要知道的是 内容的出现次数
所以在 元组 后 加上 [1] 来访问 元组的第一个内容,即 (a[0])[1]
最后得到的是一个 int类型,值为 内容的出现次数
'''
min = (a[len(a) - 1])[1]
'''
类似于 max
只不过有些 1 个区别:
max: (a [ 0 ] ) [1]
min: (a [len(a) - 1] ) [1]
区别一: [0] 与 [len(a) - 1]
[0]是访问第一个元素
[len(a) - 1] 是通过 len(a)统计所有元素个数 后 -1,来得到 出现次数最少的元素 (下标从0开始)
'''
if biao.count(max - min): # 遍历判断
print(f"Lucky Word\n{max - min}")
else:
print(f"No Answer\n0")
欢迎各位大佬斧正