解答者:IO-CtrlX
解答及供参考,若有更优解请务必告知
1. 设计一个程序, 输入三位数a, 分别输出个,十,百位.
(0<a<1000)
样例输入:
251
样例输出:
2
5
1
2. 设计一个程序, 输入整数l, 求边长为l的正方形面积, 比直径为l的圆形面积大多少.
(0<l<1000, PI取3.14, 输出结果保留两位小数)
样例输入:
3
样例输出:
1.93
#include<iostream>
using namespace std;
void separate(int num)
{
cout << num / 100 << endl;
cout << (num - (num / 100*100))/10 << endl;
cout << num % 10 << endl;
}
int main()
{
int num = 0;
cout << "Input:" ; cin >> num;
separate(num);
system("pause"); return 0;
}
#include<iostream>
using namespace std;
#define PI 3.14
void AreaDifference(int num)
{
cout << num*num - PI*(0.5)*num*(0.5)*num<< endl;
}
int main()
{
cout << "Input:" ; int num = 0; cin >> num;
AreaDifference(num);
system("pause"); return 0;
}
1. 设计一个程序, 输入a,b,c三个整数, 输出最大的数.
(MIN_INT < a,b,c < MAX_INT)
样例输入:
1 3 2
样例输出:
3
2. 打分系统
在某次考试时, 学生的提交成绩惨不忍睹
云海学长为了让大家及格可谓煞费苦心, 他苦思三天三夜, 终于想出了一套打分方案:
正确数量在0~10时, 每题6分
正确数量在11~20时, 第11~20题, 每题2分
正确数量在21~40时, 第21~40题, 每题1分
但因为需要计分的作业太多了, 希望你能帮帮云海学长, 实现该计分程序.
输入做对的题目数量n, 输出得分.
(0<=n<=40)
样例输入:
23
样例输出:
83
3. 东东哥上班
东东哥在上班途中, 可以选择走路和骑车两种方式
但他不清楚哪种方式比较快, 因为骑车需要找车, 开锁, 停车 需要耽搁很多时间.
设找到自行车, 开锁, 骑上自行车需要花27秒, 停车需要花23秒
步行每秒1.2米, 骑车每秒3.0米
给出东东哥距离公司的距离, 请问是骑车快还是走路快.
输入一个整数n, 表示到公司的距离
如果骑车快, 输出"骑车"
如果走路快, 输出"走路"
如果一样快, 输出"一样快"
样例输入:
60
样例输出:
走路
#include<iostream>
using namespace std;
void AreaDifference(int a,int b,int c)
{
a > b ? (a > c ? cout << a : cout << c) : (b > c ? cout << b : cout << c);
}
int main()
{
cout << "Input:";
int a = 0, b = 0, c = 0;
cin >> a; cin >> b; cin >> c;
AreaDifference(a,b,c);
system("pause"); return 0;
}
//最大数
void Demo21() {
//--变量声明--
//输入值
int a, b, c;
//最大值
int max;
//--接收输入--
scanf_s("%d %d %d", &a, &b, &c);
//--数据处理--
max = a;
if (b > max) {
max = b;
}
if (c > max) {
max = c;
}
//--输出--
printf("%d", max);
}
#include<iostream>
using namespace std;
int Score(int a)
{
if (a >= 0 && a <= 10) {
return a * 6;
}
else if (a >= 11 && a <= 20) {
return a * 2;
}
else {
return a * 1;
}
}
int main()
{
cout << "Input:";
int a = 0; cin >> a;
if (a >= 0 && a <= 40) { cout << Score(a) << endl; }
else { cout << "输入错误" << endl; }
system("pause"); return 0;
}
// 打分系统
void Demo22() {
//--变量声明--
// 输入
int n;
// 输出
int result;
//--接收输入--
scanf_s("%d", &n);
//--数据处理--
if (n <= 10) result = n * 6;
else if (n <= 20) result = 10 * 6 + (n - 10) * 2;
else result = 10 * 6 + 10 * 2 + (n - 20) * 1;
//--输出--
printf("%d", result);
}
#include<iostream>
using namespace std;
void Goout(int n)
{
if ((n / 1.2) == (n / 3 + 27 + 23)) { cout << "一样快"<<endl; }
else
{
(n / 1.2) < (n / 3 + 27 + 23) ? cout << "步行"<<endl : cout << "骑车"<<endl;
}
}
int main()
{
cout << "Input:";
int n = 0; cin >> n;
Goout(n);
system("pause"); return 0;
}
// 上班
void Demo23() {
//--变量声明--
// 输入
int n;
// 负数表示骑车快, 正数表示走路快, 0表示一样快
double result;
//--接收输入--
scanf_s("%d", &n);
//--数据处理--
//用骑车速度减去走路速度 如果是正数表示骑车耗时多
result = (27 + 23 + n / 3.0) - (n / 1.2);
//--输出--
// 注意double判断会有精度问题 不能直接判断==0
if (result < 0.0001) printf("骑车");
else if (result > 0.0001) printf("走路");
else printf("一样快");
}
1. 求平均年龄
01星球有学长若干名, 给出每个学长的年龄, 求01星球学长的平均年龄, 保留小数点后两位
输入:
第一行: 整数n(1<n<100), 表示人数
之后n行: 每行一个整数a(15<a<55), 表示第n个学长的年龄
输出:
一个浮点数, 保留两位小数. 表示01星球学长平均年龄
样例输入:
3
18
18
17
样例输出:
17.67
2. 张三上课时走神, 在作业上写了很多222222222222222 结果被老师发现了
张三连忙掩饰说自己在算2+22+222+2222+22222的和,
老师很欣慰, 问他算出来没有
张三很困扰, 因为草稿纸写满了2 已经不够用了
大家快帮帮张三吧
设计一个程序, 输入n和a 求Sn
Sn = a + aa + aaa + … + aaaaa(n个a)
输入: 两个整数n, a
(1<n<9), (1<=a<=9)
输出:
Sn的值
样例输入:
5 2
样例输出:
24690
样例解析: Sn = 2 + 22 + 222 + 2222 + 22222 = 24690
样例输入:
4 5
样例输出:
6170
样例解析: Sn = 5 + 55 + 555 + 5555
3. super家养了一对刚出生的兔子, 兔子出生3个月起每月都会生一对小兔子, 小兔子出生后三个月起也会每月生一对兔子
super想知道 如果兔子不死 n月后家里会有多少对兔子
设计一个程序: 输入n, 输出兔子数量
(2<n<30)
样例输入: 7
样例输出:13
样例输入: 12
样例输出: 144
4. 云海学长为了探究神秘的物理现象, 从高楼抛下一个弹球 但由于高空抛物被警察抓了, 请各位小伙伴完成他未完成的心愿
小球从某一高度落下,每次落地后反跳回原来高度的一半,再落下。
输入弹球的初始高度M和回弹次数N, 输出弹球第N次回弹后的高度 和达到该高度后所经过的距离(保留两位小数)
(0<M<1000, 0<N<50)
样例输入
1000 5
样例输出
31.25
2906.25
#include<iostream>
using namespace std;
float Age(int n)
{
float num = 0;
for (int i = 0; i < n; i++)
{
float age = 0;cin >> age;
num += age;
}
return num/n;
}
int main()
{
cout << "Input:";
int n = 0; cin >> n;
cout<<Age(n)<<endl;
system("pause"); return 0;
}
// 求平均年龄
void Demo31() {
//--变量声明--
// 人数, 临时记录变量, 学长的年龄总和
int n, temp = 0;
double age = 0;
//--接收输入--
// 注意这里age+=temp 也就是存储了所有学长年龄的和
scanf_s("%d", &n);
for (int i = 0; i < n; i++) {
scanf_s("%d", &temp);
age += temp;
}
//--数据处理--
age /= n;
//--输出--
printf("%.2lf", age);
}
#include<iostream>
using namespace std;
int Sum(int a, int n)
{
int num = 0;
for (int i = 1; i <= a; i++)
{
int b = 1;
for (int j = 0; j < i; j++)
{
b *= 10;
}
num += b / 9;
}
return num * n;
}
int main()
{
cout << "Input:"<< endl;
int a = 0,n = 0; cin >> a; cin >> n;
cout << Sum(a, n) << endl;
system("pause"); return 0;
}
#include<iostream>
using namespace std;
int Sum(int a, int n)
{
int num = 0,count = n;
for (int i = 1; i <= a; i++)
{
num += count;
count = count * 10 + n;
}
return num ;
}
int main()
{
cout << "Input:" << endl;
int a = 0, n = 0; cin >> a; cin >> n;
cout << Sum(a, n) << endl;
system("pause"); return 0;
}
// 求2222222
void Demo32() {
//--变量声明--
// 输入n, 输入a, 累加数存储变量, 答案存储变量
int n, a;
int num, result = 0;
//--接收输入--
scanf_s("%d %d", &n, &a);
num = a;
//--数据处理--
/*
num用于存储a,aa,aaa这样的数字
num = aaa
num*10 = aaa0
num*10+a = aaaa
*/
for (int i = 0; i < n; i++) {
result += num;
num = num * 10 + a;
}
//--输出--
printf("%d", result);
}
#include<iostream>
using namespace std;
int Sum(int n)
{
int a = 0, b = 1;
if (n == 1 && n == 2) { return 1; }
else
{
for (int i = 0; i < n; i++)
{
int temp = a + b;
a = b;
b = temp;
}
return a;
}
}
int main()
{
cout << "Input:";
int n = 0; cin >> n;
cout << Sum( n) << endl;
system("pause"); return 0;
}
// 数兔子
void Demo33() {
//--变量声明--
// 用户输入值 月数
int n;
// 用于存储当月 以及前1,2个月的兔子数
int m1 = 1, m2 = 1, m3 = 0;;
//--接收输入--
scanf_s("%d", &n);
//--数据处理--
//前两个月不生兔子
// 每个月的兔子数量 = 上一个月兔子数 + 上上一个月兔子数
n -= 2;
while (n--) {
m3 = m1 + m2;
m1 = m2;
m2 = m3;
}
//--输出--
printf("%d", m3);
}
#include<iostream>
using namespace std;
float YunHai(float m,float n)
{
}
int main()
{
cout << "Input:";
float m = 0, n = 0; cin >> m; cin >> n;
cout << YunHai( m,n ) << endl;
system("pause"); return 0;
}
1. 使用程序打印九九乘法表
样例输出:
1 * 1 = 1
1 * 2 = 2 2 * 2 = 4
1 * 3 = 3 2 * 3 = 6 3 * 3 = 9
….
2. 求素数
设计一个程序, 输入N, 输出0~N之间的所有素数
(0<N<MAX_INT)
样例输入:
100
样例输出:
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
3.小游戏: 猜数字
输入整数n(0<n<100), 想让程序猜到的值
如果程序没有猜中, 则提示太大/太小 并让程序接着猜测
程序通过二分法不断缩小猜测范围, 直到猜中n
例如n = 39
程序第一次猜测50, 判断数值太大
第二次猜测25, 判断数值太小
第三次猜测37 判断数值太小
43 大
40 大
38 小
39 正确
输入: n 表示被猜测值
输出: 每行输出一个整数, 表示程序当前猜测的数字
最终行输出猜测的次数
样例输入:
39
样例输出:
50
25
37
43
40
38
39
最终猜测了7次
4.打印菱形
输入菱形的边长n, 打印一个对应大小的菱形
(1<n<100)
样例输入: 5
样例输出:
*
***
*****
*******
*********
*******
*****
***
*
#include<iostream>
using namespace std;
void ChengFaKJ()
{
for (int i = 1; i <= 9; i++)
{
for (int j = 1; j <= i; j++)
{
cout << j << " * " << i << " = " << i * j<<" ";
}
cout << endl;
}
}
int main()
{
ChengFaKJ();
system("pause"); return 0;
}
// 乘法表
void Demo41() {
//--变量声明--
//--接收输入--
//--数据处理--
//--输出--
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
printf("%d * %d = %d\t", j, i, i * j);
}
printf("\n");
}
}
#include<iostream>
using namespace std;
void ChengFaKJ(int n)
{
int i, j;
for (i = 2; i <= n; i++)
{
for (j = 2; j < sqrt(i); j++)
{
if (i % j == 0) break;
}
if (j == int(sqrt(i)) + 1)
cout << i << endl;
}
}
int main()
{
int n = 0; cin >> n;
if (n < 2) cout << "NULL";
else if (n == 2)cout << 2 <<endl;
else
{
ChengFaKJ(n);
}
system("pause"); return 0;
}
// 求素数
void Demo42() {
//--变量声明--
// 输入值
int N;
// 标识符 值为1表示素数 值为0表示非素数
int flag;
//--接收输入--
scanf_s("%d", &N);
//--数据处理--
//--输出--
for (int i = 2; i <= N; i++)
{
flag = 0;
for (int j = 2; j < i/*sqrt(i)*/; j++)
{
// 如果i%j为0 则该数字是非素数 0表示假 !取反为真
if (!(i % j)){
flag = 1;
break;
}
}
//如果flag是0 表示是素数 打印
if (!flag) printf("%d\n", i);
}
}
PS:
sqrt()
函数在c语言中用于计算一个非负实数的平方根,开根号;其语法为double sqrt(double)
。在sqrt()函数中没有sqrt (int)
,但是返回值可以为int,返回值可以与int类型进行运算。
等同用法:j*j<i
for(int j=2;j*j<=i;j++)//j*j<i;相当于对i开了根号,j只用加到i的平方根,而不用加到i-1减少了计算量
{
if((i%j)==0)
{
flag++;//如果有因数,flag+1
break;//有因数,直接结束内层循环,减少计算量
}
}
详细分析:
质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。“1”既不是素数,也不是合数。
因为如果一个数不是素数是合数,那么一定可以由两个自然数相乘得到,其中一个大于或等于它的平方根,一个小于或等于它的平方根。并且成对出现,所以只用计算到该数的平方根以下看除了1有没有该数的因数,若没有,则是素数。
(1)质数p的约数只有两个:1和p。
(2)初等数学基本定理:任一大于1的自然数,要么本身是质数,要么可以分解为几个质数之积,且这种分解是唯一的。
(3)质数的个数是无限的。
(4)大于10的质数中,个位数只有1,3,7,9。
// 猜数字
void Demo43() {
//--变量声明--
// 用户输入 让程序猜的数字
int n;
// 程序猜测的次数, 二分猜测法的上下限
int count = 0, max = 100, min = 0;
//猜测值
int mid;
//--接收输入--
scanf_s("%d", &n);
do{
//--数据处理--
/*
猜测值 = (上限 + 下限) /2
如上限100 下限0 猜测值=50
上限100 下限50 猜测值=75
如果猜测值比n小, 则下限 = 猜测值+1
如果猜测值比n大, 则上d限 = 猜测值-1
*/
count++;
mid = (max + min) / 2;
if (mid > n) {
max = mid - 1;
}
else if (mid < n) {
min = mid + 1;
}
//--输出--
printf("%d\n", mid);
} while (mid != n);
printf("最终猜测了%d次", count);
}
#include<iostream>
using namespace std;
int main()
{
cout << "Input:";
int n;cin >> n;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < (n - 1 - i); j++)
{
cout << " ";
}
for (int j = 0; j < 2 * i + 1; j++)// *号是等差序列的公式2n+1
{
cout << "*";
}
cout << endl;
}
//难点:下方三角形:思路一
for (int i = 0; i < n - 1; i++)//打印店层数一定是奇数,最大的一层在上面被打印
{
for (int j = 0; j < i + 1; j++)
{
cout << " ";
}
for (int j = 0; j < 2 * (n - 1) - (2 * i + 1); j++)//2(n-1)是菱形分割线往下的第一行,是个定值,把下面的部分看成是一个由*组成的矩形,矩形的每一行减去递增的等差数列2i+1个*形成递减的等差数列。
{
cout << "*";
}
cout << endl;
}
system("pause");
return 0;
}
#include<iostream>
using namespace std;
int main()
{
cout << "Input:";
int n; cin >> n;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < (n - 1 - i); j++)
{
cout << " ";
}
for (int j = 0; j < 2 * i + 1; j++)// *号是等差序列的公式2n+1
{
cout << "*";
}
cout << endl;
}
//另一思路:
for (int i = n - 2 ; i >= 0; i--)//打印店层数一定是奇数,最大的一层在上面被打印
{
//与上面完全相同
for (int j = 0; j < (n - 1 - i); j++)
{
cout << " ";
}
for (int j = 0; j < 2 * i + 1; j++)
{
cout << "*";
}
cout << endl;
}
system("pause");
return 0;
}
// 打印菱形
void Demo44() {
//--变量声明--
//菱形边长
int n;
//--接收输入--
scanf_s("%d", &n);
//--数据处理--
//坐标系思路
//--输出--
// 当n为5时, 坐标系的上下限分别是-4~4 最大高/宽度为9
for (int i = -n+1; i < n; i++) {//层数。-4(包括-4本身)到4,共9层。
for (int j = -n+1; j < n; j++) {//每一层内的元素数。-4(包括-4本身)到4,共9个元素。
// i的绝对值+j的绝对值 小于n 则在菱形范围内
if (abs(i) + abs(j) < n) {
printf("*");
}
else {
printf(" ");
}
}
printf("\n");
}
}
详细分析:
用坐标系的思路: 设坐标点(x,y),以菱形的中心为坐标原点。 当x的绝对值 + y的绝对值 小于n时, 这个坐标点在菱形内 当x的绝对值 + y的绝对值 大于等于n时, 这个坐标点在菱形外
以边长为5的菱形为例:
y
^
|
|
*(0,4)
***
*****
*******
****.****(4,0)——————————>x
*******
*****
***
*
在第一象限中的菱形边长为y = -x + 4,这个直线就是临界,y + x = 4,当y + x > 4时这个坐标点在菱形外。如: (2,2)在菱形内, (3,2)在菱形外, (-4,0)在菱形内, (4,1)在菱形外。
同理,当配合绝对值 也就是正负号就可以画出4条线,构成菱形。
1. 删除重复值
阿伟学长在开发一款游戏, 他希望玩家已经获得的道具会降低爆率, 避免玩家获得太多重复的道具
但玩家背包中道具是乱序且不确定的, 为了减小判断的运算量, 需要先对数据进行去重.
设计一个程序, 输入数据数量N, 以及N个整数Ni. 将该组数据去重后打印
(1<N<100, 0 <= Ni <= MAX_INT)
样例输入:
10
1 3 2 6 2 6 4 8 2 6
样例输出:
1 3 2 6 4 8
2. 数字环
有一个长度为n的数字环, 将每个数字往后移动m位, 使其成为一个新的数字环
输入:
第一行: 整数n 表示有n个数字
第二行: n个整数Ni, 表示数字环的每个元素
第三行: 整数m 表示每个元素需要往后移动m位
输出: 移动后的新数字环
(1<=m<n<100, MIN_INT<Ni<MAX_INT)
样例输入:
10
1 2 3 4 5 6 7 8 9 10
2
样例输出:
9 10 1 2 3 4 5 6 7 8
3. 排队枪毙
小约参与了犹余游戏, 在这个游戏中最后活下来的人才能获得胜利.
游戏规则是这样的, n个玩家们围成一个圈, 从第一个玩家开始报数
报到m的人被枪毙, 下一个人接着从1开始报数.
直到最后一个活下来的人获得胜利.
小约现在开始选编号了, 已知参与的玩家数量为n, 被枪毙的数是m. 小约要选到几号位置才会活下来.
(1<m<n<100)
设计一个程序, 输入n和m, 输出最后的胜利者
样例输入: 10 3
样例输出: 4
#include<iostream>
#include<algorithm>
using namespace std;
void SortShuZ(int n,int a[])
{
sort(a, a + n); //将数组从小到大排序
for (int i = 0; i < n; i++)
{
if (a[i] != a[i + 1]) cout << a[i] << " ";
}
}
int main()
{
int n;cin >> n;
int a[100] = {0};
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
SortShuZ(n,a);
system("pause"); return 0;
}
// 去重
void Demo51() {
//--变量声明--
//数据总数, 去重后的数量
int N, len;
//待去重的数据
int arr[100];
//--接收输入--
scanf_s("%d", &N);
len = N;
for (int i = 0; i < N; i++) {
scanf_s("%d", &arr[i]);
}
//--数据处理--
/*
将每个元素都和后面的元素进行判断
如果[i]和[j]值重复, 将[j]的值设为-1. 并且len--
{1,3,2,6,-1,-1,4,8,-1,-1}
都判断一遍后, 将值为-1的元素 用后一个元素值进行覆盖
{1,3,2,6,4,8}
*/
for (int i = 0; i < N; i++)
{
for (int j = i + 1; j < N; j++)
{
if (arr[i] == -1) break;
if (arr[i] == arr[j])
{
arr[j] = -1;
len--;
}
}
}
for (int i = 0, j = 0;j < j++)
{
arr[i] = arr[j];
if (arr[i] != -1)
{
i++;
}
}
//--输出--
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
}
/*
快慢指针思路
i表示慢下标, j表示快下标
快下标: 每次循环往后移动一位
慢下标: 条件符合时往后移动一位
每次循环时, arr[i] = arr[j]
慢下标条件: 覆盖后, 如果当前[i]的值不为-1 则i++(往后移动一位)
下面样例的截取点是在arr[i] = arr[j]后 i++前
ij
1 2 -1 3 -1 4 -1 5 6
ij
1 2 -1 3 -1 4 -1 5 6
ij
1 2 -1 3 -1 4 -1 5 6
i j
1 2 3 3 -1 4 -1 5 6
i j
1 2 3 -1 -1 4 -1 5 6
i j
1 2 3 4 -1 4 -1 5 6
i j
1 2 3 4 -1 4 -1 5 6
i j
1 2 3 4 5 4 -1 5 6
i j
1 2 3 4 5 6 -1 5 6
*/
#include<iostream>
using namespace std;
//移动数组
void ShuZiH(int n,int a[])
{
int temp = a[0];
for (int i = 0; i < n; i++)
{
a[i] = a[i + 1];
}
a[n - 1] = temp;
}
//输出数组
void Print(int n,int a[])
{
for (int i = 0; i < n; i++)
{
cout << a[i] << " ";
}
}
int main()
{
int n;cin >> n;
//输入数组
int a[100] = {0};
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
//循环移动次数
int m; cin >> m;
for (int i = 0; i < m; i++)
{
ShuZiH(n, a);
}
//打印移动后的数组
Print(n,a);
system("pause"); return 0;
}
// 数字环
void Demo52() {
//--变量声明--
// 数字环存储数组, 长度, 移动位数
int arr[100], len, m;
// 转换后数组
int result[100];
//--接收输入--
scanf_s("%d", &len);
for (int i = 0; i < len;i++) {
scanf_s("%d", &arr[i]);
}
scanf_s("%d", &m);
//--数据处理--
for (int i = 0; i < len; i++) {
result[(i + m) % len] = arr[i];
}
//巧妙之处(i + m) % len,例如当123456六个数移动m=5位,以3为例,当3向后移动5位后到了2的位置,(3+5)%6=2
//注意这种处理越界的方法!
//--输出--
for (int i = 0; i < len; i++) {
printf("%d ", result[i]);
}
}
巧妙之处(i + m) % len
,注意这种处理越界的方法!
详细分析:
最终数组result[(i + m) % len]
目标原始数组arr[i]
例如当123456六个数移动m=5位,最后顺序应是234561
在for循环中arr[i]从1-6按顺序赋值给result,需要排序的是result,
(0+5)%6 = 5 result[5] = 1//向后移动5位,没有超出长度,所以余数还是5
(1+5)%6 = 0 result[0] = 2
(2+5)%6 = 1 result[1] = 3
(3+5)%6 = 2 result[2] = 4//向后移动8位,超出了长度6,即超出了界限,超出了2,余数为2
(4+5)%6 = 3 result[3] = 5
(5+5)%6 = 4 result[4] = 6
核心不过如此:向后移动几位,除以这个数组的长度,余数就是多出了这个数组长度的值,相当于你要移动的位数减去原数组的长度。
进阶玩法见下面的密码加密题目
// 约瑟夫环
void Demo53() {
//--变量声明--
// 玩家数量, 被枪毙数, 玩家当前状况
// 值为1表示存活 值为0表示被枪毙了
int n, m, arr[100];
// 目前活着的人数, flag用于标记当前数到几
int num, flag = 0;
//--接收输入--
scanf_s("%d %d", &n, &m);
num = n;
for (int i = 0; i < n; i++) {
arr[i] = 1;
}
//--数据处理--
for (int i = 0; num - 1; i++)//for循环运行过程中的判断条件是num - 1,当for循环1号位置(num - 1)为0时for循环不成立,退出。
{
if (i == n) i = 0;//在循环运行过程中i++,当i等于总人数时将i归零,防止下面的数组越界(注意是n,不是n - 1,因为arr[n]就是越界了,arr[n - 1]是修后一个人,不能让i = n)
if (arr[i]) //arr[i]是0或者1,是0则跳过,是1运行if语句
{
flag++;//1代表人未被枪毙,在存活的人里报数
if (flag == m)
{
arr[i] = 0;
flag = 0;//并且重新报数
num --;//未被枪毙的人的数量减去1,当num = 1时代表只有一个人,此时num - 1 = 0,退出。
}
}
}
//--输出--
for (int i = 0; i < n; i++) {
if (arr[i]) printf("%d", i + 1);
}
}
1. 矩阵转置
输入一个数字构成的矩形, 将矩形的值进行转置后打印
输入:
第一行 正整数n(1<n<10), 表示矩阵的边长
随后输入一个矩阵
输出:
转置后的矩阵
样例输入:
3
1 2 3
4 5 6
7 8 9
样例输出:
1 4 7
2 5 8
3 6 9
2. 颈椎病治疗
最近云海学长一直对着电脑改bug, 颈椎不舒服, 希望各位小伙伴帮云海学长治治
提供一张图片, 将图片旋转后再发给云海学长, 这样学长看图的时候就需要歪着脖子, 时间久了, 颈椎病就治好了
输入一个数字构成的矩形, 将矩形的值进行90度旋转后打印
输入:
第一行 正整数n(1<n<10), 表示矩阵的边长
随后输入一个矩阵
输出:
90度旋转后的矩阵
样例输入:
3
1 2 3
4 5 6
7 8 9
样例输出:
7 4 1
8 5 2
9 6 3
3. 杨辉三角
输入n(1<n<10), 打印高度为n的杨辉三角
样例输入: 5
样例输出:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
*4. 包围圈
东东哥在一场军事演练中, 需要对一片正方形森林进行排查,
为了防止被包围, 东东哥需要先排查外围才能进一步深入
输入: 正整数n(1<n<10), 表示森林的边长
输出: 东东哥排查森林的顺序
样例输入:
4
样例输出:
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
#include<iostream>
using namespace std;
const int N = 10;
//按数字顺序生成二维数组
void FuZhi(int n,int a[][10])
{
int k = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
k++;
a[i][j] = k;
}
}
}
//转置,行和列互换
void ZhuanZ(int n,int a[][N])
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (i > j)
{
int t = a[i][j];
a[i][j] = a[j][i];
a[j][i] = t;
}
}
}
}
//打印
void Print(int n,int a[][10])
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cout<<a[i][j];
}
cout << endl;
}
}
int main()
{
int n; cin >> n;
if (n > 1 && n <= N)
{
int a[N][N];
FuZhi(n, a);
Print(n, a);
cout << "转置后:" << endl;
ZhuanZ(n, a);
Print(n, a);
}
system("pause"); return 0;
}
// 矩阵转置
void Demo61() {
//--变量声明--
// 矩阵边长, 矩阵本身, 转置后数组
int size, arr[10][10], result[10][10];
//--接收输入--
scanf_s("%d", &size);
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
scanf_s("%d", &arr[i][j]);
}
}
//--数据处理--
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
result[j][i] = arr[i][j];
}
}
//--输出--
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
printf("%d ", result[i][j]);
}
printf("\n");
}
}
// 颈椎病
void Demo62() {
//--变量声明--
// 矩阵边长, 矩阵本身, 转置后数组
int size, arr[10][10], result[10][10];
//--接收输入--
scanf_s("%d", &size);
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
scanf_s("%d", &arr[i][j]);
}
}
//--数据处理--
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
result[j][size - i - 1] = arr[i][j];
}
}
//--输出--
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
printf("%d ", result[i][j]);
}
printf("\n");
}
}
详细分析:
//数组下标变化:
假设size为3
0 1 2
0 1 2 3
1 4 5 6
2 7 8 9
->
0 1 2
0 7 4 1
1 8 5 2
2 9 6 3
x1 y y x2
[0][0]->[0][2]
[0][1]->[1][2]
[1][2]->[2][1]
[2][1]->[1][0]
//规律:
x转y ,y转x
x转y时 size - x = y,由于下标开始值为0,所以size - 1 - x = y
y转x时 y = x
如上,y下标原封替换x坐标,但是x下标需要被size - 1 减后才能作为新数组的y下标。
#include<iostream>
using namespace std;
void Print(int n, int a[][10]);
void YH(int n)
{
int a[10][10];
//计算杨辉三角, 以下三角矩阵的形式存放在二维数组
for (int i = 0; i < n; i++) {
a[i][0] = 1;
a[i][i] = 1;
for (int j = 1; j < i; j++)
a[i][j] = a[i - 1][j - 1] + a[i - 1][j]; //i不可能取值为0导致地址越界
}
Print(n,a);
}
void Print(int n,int a[][10])
{
for (int i = 0; i < n; i++) {
for (int j = 1; j <= n - 1 - i; j++) //打印每行开始的空格
cout << " ";
for (int j = 0; j <= i; j++) //每行打印的数据个数
cout << a[i][j] << " ";
cout << endl;
}
}
int main() {
int n; cin >> n;
YH(n);
system("pause"); return 0;
}
// 杨辉三角
void Demo63() {
//--变量声明--
// 杨辉三角的高度
int n;
// 存储用数组, 注意杨辉三角只会占用一半的空间, 所以这里可以用malloc动态分配来避免空间浪费
int arr[10][10];
//--接收输入--
scanf_s("%d", &n);
arr[0][0] = 1;
//--数据处理--
// 左右两侧数据直接填充即可
for (int i = 1; i < n; i++) {
arr[i][0] = arr[i][i] = 1;
for (int j = 1; j < i; j++) {
arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];
}
}
//--输出--
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
// 包围圈
void Demo64() {
//--变量声明--
int size, tree[10][10];
// 当前坐标xy, 移动方向toward 0左 1下 2右 3上, 填充数
// 注意 由于第一次探查前会先移动 x++ 所以x需要修正为-1
int x = -1, y = 0, toward = 0, num = 0;
// 一个方向的移动步数
int s;
//--接收输入--
scanf_s("%d", &size);
s = size;
//--数据处理--
// 移动规律 如果是4 则是4+3+3+2+2+1+1 = 16 同理 如果是5 5+4+4+3+3+2+2+1+1
// 外部循环: 每奇数次循环, 最大步数-1. 一个方向移动完后 对方向进行修改
// 内部循环: 循环(步数)次, 每次移动根据方向对xy进行修改
for (int i = 0; num<size*size; i++) {
// 奇数次循环 最大步数-1
if (i % 2 == 1) s--;
for (int j = 0; j < s; j++) {
// 获取方向并移动
switch (toward) {
case 0:
x++;
break;
case 1:
y++;
break;
case 2:
x--;
break;
case 3:
y--;
break;
}
tree[y][x] = ++num;
}
// 改变方向 注意 当toward为3 也就是向上时, 需要取模操作 也就是变为0
// (1+1) %4 = 2 (3+1) %4=0
toward = (toward + 1) % 4;
}
//--输出--
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
printf("%d ", tree[i][j]);
}
printf("\n");
}
}
1. 大小写转换
设计一个程序, 输入一行字符串, 将其中大写转为小写, 小写转为大写. 其余字符不变
(字符串长度<100)
样例输入: hELLO wORLD!
样例输出: Hello World!
2. 转反串符字
累很天聊他和长学海云 ,话说着倒欢喜三张
身彼施还道之彼以算打长学海云是于
出输后列排序反串符字个这将 ,串符字串一入输 ,序程个一计设
(001>度长串符字)
!dlroW olleH :入输例样
Hello World! :出输例样
3. 开挂很危险
最近网络盗号严重, 张三又喜欢开外挂(大家不要学)
于是张三打算出一个安全的密码, 避免开外挂后被盗号
请各位小伙伴帮忙, 判定一下张三的密码是否安全
安全密码的判定:
1. 长度在8~16之间
2. 开头必须是大写
3* 密码最少包含一个小写字母, 一个数字, 一个特殊符号
特殊符号包括~!@#$%*
设计一个程序 输入密码字符串
如果密码安全, 打印true, 否则打印false
(字符串长度<100)
样例输入:
Aa123!!!!!
样例输出:
true
4. 密码加密
自从上次张三密码变复杂后, 再也没有被盗过号
但他觉得密码还是不够复杂, 于是又进行了二次加密
然后..他忘记二次加密后的密码了
小伙伴赶紧帮他找找
张三的加密方式是这样的:
对于每个字母和数字, 按字母表/数字顺序往后挪5位
(如果超过了 则从头开始, 比如'z'转换后变成'e', '9'转换后变成'4')
符号不变
如密码: AaZz09!!!
加密后: FfEe54!!!
设计一个程序, 输入加密前的密码 打印加密后的密码
(密码长度 <= 16)
样例输入: AaZz09!!!
样例输出: FfEe54!!!
#include<iostream>
#include<string>
using namespace std;
void SwapStr(string char1)
{
int n = strlen(char1.c_str());
for (int i = 0; i < n; i++)
{
if ((int)char1[i] > 65 && (int)char1[i] < 90) { cout << (char)(char1[i] + 32); }
else if ((int)char1[i] > 97 && (int)char1[i] < 122){cout << (char)(char1[i] - 32); }
else { cout << char1[i]; }
}
}
int main()
{
string n; getline(cin, n);;
SwapStr(n);
system("pause"); return 0;
}
// 大小写转换
void Demo71() {
//--变量声明--
// 存放字符串的数组
char str[100];
//--接收输入--
gets_s(str, 100);
//--数据处理--
// 判断ascii码是否在大小写范围内 如果在 则手动转换
for (int i = 0; str[i] != '\0'; i++) {
if (str[i] >= 65 && str[i] <= 90) {
str[i] += 32;
}
else if (str[i] >= 97 && str[i] <= 122) {
str[i]-= 32;
}
}
//--输出--
printf("%s", str);
}
#include<iostream>
#include<string>
using namespace std;
void SwapStr(string char1)
{
int n = strlen(char1.c_str());
for (int i = 0; i < n; i++)
{
cout << char1[n - 1 - i] ;
}
}
int main()
{
string n; getline(cin, n);;
SwapStr(n);
system("pause"); return 0;
}
// 字符串反转
void Demo72() {
//--变量声明--
// 存放字符串的数组, 存放答案的数组
char str[100], result[100];
// 字符串的长度
int len;
//--接收输入--
gets_s(str, 100);
//--数据处理--
// 获取长度
for (len = 0; str[len] != '\0'; len++);
// 倒序填入result字符串
for (int i = 0; i < len; i++) {
result[i] = str[len - i - 1];
}
result[len] = '\0';
//--输出--
printf("%s", result);
}
#include<iostream>
#include<string>
using namespace std;
bool MiMa(string char1)
{
int n = strlen(char1.c_str());//字符串长度
if (n < 8 || n > 16 || (int)char1[0] < 65 || (int)char1[0] > 90)return 0;
for (int i = 1; i < n; i++)
{
int j = (int)char1[i];
if ((j >= 48 && j <= 57) || (j <= 97 && j >= 65) || j == 126 || j == 33 || j == 64 || j == 35 || j == 36 || j == 37 || j == 42) return 1;
}
}
int main()
{
string n; cin >> n;
MiMa(n) == 1 ? cout << "true" << endl : cout << "false" << endl;
system("pause"); return 0;
}
// 安全密码
void Demo73() {
//--变量声明--
// 用户输入
char password[100];
// 用于验证是否合法, 0:长度, 1:开头大写, 2:包含小写, 3:包含数字, 4:包含特殊符号
int flag[5] = { 0 };
//--接收输入--
gets_s(password,100);
//--数据处理--
//开头大写判断
if (password[0] >= 65 && password[0] <= 90) flag[0] = 1;
for (int i = 1; password[i] != '\0';i++) {
//小写字母
if (password[i] >= 97 && password[i] <= 122) flag[2] = 1;
//数字
else if (password[i] >= 48 && password[i] <= 57) flag[3] = 1;
//特殊符号
else if (password[i] == '~' ||
password[i] == '!' ||
password[i] == '@' ||
password[i] == '#' ||
password[i] == '$' ||
password[i] == '%' ||
password[i] == '*'
) flag[4] = 1;
// 长度
flag[1] = (i >= 8 && i <= 16);
}
//--输出--
if (flag[0] && flag[1] && flag[2] && flag[3] && flag[4]) {
printf("true");
}
else {
printf("false");
}
}
#include<iostream>
#include<string>
using namespace std;
void SwapStr(string char1)
{
int n = strlen(char1.c_str());
for (int i = 0; i < n; i++)
{
if ((int)char1[i] >= 65 && (int)char1[i] <= 90)
{
(int)char1[i] > 85 ? cout << (char)((int)char1[i] - 21) : cout << (char)(char1[i] + 5);
}
else if ((int)char1[i] >= 97 && (int)char1[i] <= 122)
{
(int)char1[i] > 117 ? cout << (char)(char1[i] - 21) : cout << (char)(char1[i] + 5);
}
else if ((int)char1[i] >= 48 && (int)char1[i] <= 57)
{
(int)char1[i] > 52 ? cout << (char)(char1[i] - 5) : cout << (char)(char1[i] + 5);
}
else { cout << char1[i]; }
}
}
int main()
{
string n; getline(cin, n);;
SwapStr(n);
system("pause"); return 0;
}
// 加密
void Demo74() {
//--变量声明--
char password[17];
//--接收输入--
gets_s(password, 16);
//--数据处理--
/*
思路: 先减到0~25 然后+5取模
如果超过25了(字母xyz), 则会因为取模成bcd
比如z
90 - 65=25
25 + 5 = 30 %26 = 4
4+65 = 69 = e;
数字同理
*/
for (int i = 0; password[i] != '\0'; i++) {
//大写字母
if (password[i] >= 65 && password[i] <= 90) {
password[i] = (password[i] - 65 + 5) % 26 + 65;
}
//小写字母
else if (password[i] >= 97 && password[i] <= 122) {
password[i] = (password[i] - 97 + 5) % 26 + 97;
}
//数字
else if (password[i] >= 48 && password[i] <= 57) {
password[i] = (password[i] - 48 + 5) % 10 + 48;
}
}
//--输出--
printf("%s", password);
}
详细分析:
越界问题:如果超过25了(字母xyz), 则会因为取模成bcd
//防止越界处理思路:
先减到0~25(思路与上面题目数字环相同,直接使用数组长度取模的前提是数组的初始值是0),然后+5取模,余数就是超出的长度。
比如z
90 - 65=25
25 + 5 = 30 %26 = 4
4+65 = 69 = e;
//等同思路:
先+5,然后在取模时用(该数组长度26 + 该数组初始长度65)取模
比如z
90 + 5 = 95
95 % (26 + 65) = 4
4+65 = 69 = e;
1. 根据以下要求, 实现一套登录功能
已知有全局变量
int ids[5] = {10001,10002,10003,10004};
char names[5][10] = {"张三", "李四", "王五", "赵六"};
char passwords[5][16] = {"aaaaa","bbbbb","ccccc","ddddd"};
int uNum = 4;
其中 每个下标对应一套用户数据(id, 名称, 密码)
如下标[1]: 对应10002, 李四, bbbbb
根据以下的函数声明和注释, 写出相应的函数实现
/*
功能: 根据id 查询用户是否存在, 如果存在返回用户名, 如果不存在返回空
参数:
uid: 用户id
返回值:
如果用户存在, 返回用户名.
如果用户不存在, 返回NULL
*/
char* selectUserById(int uid);
/*
功能: 根据id 查询用户密码, 如果存在返回用户密码, 如果不存在返回空
参数:
uid: 用户id
返回值:
如果密码存在, 返回密码.
如果密码不存在, 返回NULL
*/
char* selectPassById(int uid);
----------------------------------------------------
/*
功能: 传入用户id和密码, 根据上面两个函数(selectUserById, selectPassById)来获取相应用户数据, 并判断是否登录成功
传入用户id 查询用户名是否存在, 并获取用户密码
如果用户存在 则判断密码是否正确
参数:
uid: 用户账户
password: 用户密码
返回值:
如果账号不存在, 返回1
如果密码错误, 返回2
如果登录成功, 返回0
*/
int login(int uid, char* password);
-----------------------------------------------------
/*
功能: 提示用户输入账号密码, 根据login函数判断是否登录成功,
如果登录成功提示正在进入首页
如果登录失败
密码错误: 提示密码错误, 并让用户重新登录
账号不存在: 提示账号不存在, 并提示正在进入注册界面
参数: 无
返回值: 无
*/
void showLoginPage();
样例输入:
10001
aaaaa
样例输出:
登录成功, 正在进入首页
样例输入:
10001
aaaab
样例输出:
密码错误, 请重新登录
提示: 先输入数字再输入回车, 可能会出现回车符号被%s或者gets接收的情况, 导致密码无法被接收,
可以用getchar接收回车来解决.
对应知识点: 键盘缓冲区
2. 上面有用虚线将函数划分为3种, 这三种函数有哪些区别(可以百度查询"三层架构"). 根据这种思路 实现一套注册功能.
非常容易出错的点!:如何比较两个字符串是否相等?直接==?错误!
使用strcmp函数来比较!
#include<iostream>
using namespace std;
int ids[5] = { 10001,10002,10003,10004 };
char names[5][10] = { "张三", "李四", "王五", "赵六" };
char passwords[5][16] = { "aaaaa","bbbbb","ccccc","ddddd" };
int uNum = 4;
char* selectUserById(int uid)
{
for (int i = 0; i < uNum; i++)
{
if (ids[i] == uid) return names[i];
}return NULL;
}
char* selectPassById(int uid)
{
for (int i = 0; i < uNum; i++)
{
if (ids[i] == uid) return passwords[i];
}return NULL;
}
int login(int uid, char* password)
{
if (selectUserById(uid) != NULL)
{
if (strcmp(password, selectPassById(uid)) == 0)return 0;
return 2;
}
return 1;
}
void showLoginPage()
{
cout << "请输入账号和密码:" << endl;
int u; cin >> u;
char p[16] = { 0 }; cin >> p;
switch (login(u, p))
{
case 1:cout << "账号不存在,进入注册界面"; break;
case 0:cout << "登录成功"; break;
case 2:cout << "密码错误, 并让用户重新登录"; break;
}
}
int main()
{
showLoginPage();
system("pause"); return 0;
}
/*
功能: 根据id 查询用户是否存在, 如果存在返回用户名, 如果不存在返回空
参数:
uid: 用户id
返回值:
如果用户存在, 返回用户名.
如果用户不存在, 返回NULL
*/
char* selectUserById(int uid) {
for (int i = 0; i < uNum; i++) {
if (ids[i] == uid) {
return names[i];
}
}
return NULL;
}
/*
功能: 根据id 查询用户密码, 如果存在返回用户密码, 如果不存在返回空
参数:
uid: 用户id
返回值:
如果密码存在, 返回密码.
如果密码不存在, 返回NULL
*/
char* selectPassById(int uid) {
for (int i = 0; i < uNum; i++) {
if (ids[i] == uid) {
return passwords[i];
}
}
return NULL;
}
/*
功能: 传入用户id和密码, 根据上面两个函数(selectUserById, selectPassById)来获取相应用户数据, 并判断是否登录成功
传入用户id 查询用户名是否存在, 并获取用户密码
如果用户存在 则判断密码是否正确
参数:
uid: 用户账户
password: 用户密码
返回值:
如果账号不存在, 返回1
如果密码错误, 返回2
如果登录成功, 返回0
*/
int login(int uid, char* password) {
if (selectUserById(uid) == NULL) {
return 1;
}
char* pass = selectPassById(uid);
if (strcmp(password, pass) != 0) {
return 2;
}
return 0;
}
/*
功能: 提示用户输入账号密码, 根据login函数判断是否登录成功,
如果登录成功提示正在进入加载界面
如果登录失败
密码错误: 提示密码错误, 并让用户重新登录
账号不存在: 提示账号不存在, 并提示正在进入注册界面
参数: 无
返回值: 无
*/
void showLoginPage() {
//--变量声明--
//用户id
int uid;
//用户密码
char password[17];
//结果选项
/* 如果账号不存在, 返回1
如果密码错误, 返回2
如果登录成功, 返回0
*/
int result;
//--接收输入--
scanf_s("%d", &uid);
//处理掉输入的回车符号
getchar();
gets_s(password, 16);
//--数据处理--
result = login(uid, password);
//--输出--
switch (result) {
case 1:
printf("账号不存在, 正在进入注册界面");
break;
case 2:
printf("密码错误, 请重新登录");
break;
case 0:
printf("登录成功, 正在进入首页");
break;
}
}
#include<iostream>
using namespace std;
int ids[5] = { 10001,10002,10003,10004 };
char names[5][10] = { "张三", "李四", "王五", "赵六" };
string passwords[5] = { "aaaaa","bbbbb","ccccc","ddddd" };
int uNum = 4;
int BLL_U(int& u);
void DAL(int& u, string p);
//(UI)UI界面
void UI()
{
cout << "注册>>" << endl << "请输入账号:" << endl;
int u; cin >> u; string p; cin >> p;
if (BLL_U(u) > 0) cout << "用户名已存在!" << endl;
else
{
DAL(u, p);
cout<<"用户注册成功!" << endl;
}
}
//(BLL)检测用户名是否存在
int BLL_U(int &u)
{
int flag = 0;
for (int i = 0; i < uNum; i++)
{
if (ids[i] == u)flag ++;
}
return flag;
}
//(DAL)修改数据
void DAL(int& u, string p)
{
ids[uNum] = u;
passwords[uNum] = p;
}
int main()
{
UI();
system("pause"); return 0;
}