新形态C语言程序设计游戏化任务教程:第6章17关-20关

2024-08-28 19:52

本文主要是介绍新形态C语言程序设计游戏化任务教程:第6章17关-20关,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言:

题目链接
进入链接后,点击实践项目,以下题目为6.8.17到6.8.20,

古老的纸牌游戏

任务描述:
本题所述的麻将纸牌只包括3大类别的牌:条、饼、万(不包括老千、红花和白花)。每大类的牌点数都有从1至9,共27种牌,每种牌有4张,一副牌只取108张。
和牌规则:
5张牌和(音:胡)牌的规则如下:
1.必须有一个对子,即两张相同的牌,称为“掌”,比如:两个2饼做掌,两个4条做掌等。
2.剩余的3张牌,如果正好形成“哈子”(3个一样的牌,如3个2饼,麻将中称为一刻)或者“一趟副”(同种类点数连续,如1条、2条、3条),就可以和牌了。
3.输入的牌肯定是4张。
4.条用T表示,饼用B表示,万用W表示。
也可以理解为和牌类型有以下几种(11表示一对,123表示一副、111表示一刻):
(1)11、123(1副1对)
(2)11、111(1哈1对)
假设你手中有4张牌,如果加上别人打出手的1张牌或你自己再摸1张牌,就构成和牌,则称“有叫儿”(麻将称为听牌)。
给你4张牌,你知道自己是否“有叫儿”并和什么牌吗?

输入格式:

输入共一行,代表一组数据(一手牌)。
在一行中包含以1个空格分隔的4个数据,每个数据由1个数字加1个大写字母构成,代表1张纸牌,4个数据代表一手牌。(例如:1T代表1条、2W代表2万、9B代表9饼)。

输出格式:

该组数据如果“有叫儿”,则依次输出可以和的牌(叫儿),如果有多个“叫儿”,按“条、饼、万”的顺序输出,同一种类的牌,按点数从小到大输出,每个“叫儿”之后输出一个圆点句号。
该组数据如果“没有叫儿”,则输出:No jiaor。

输入样例(平和2张):

4B 4B 3T 4T

输出样例:

2T.5T.

输入样例(和对倒2张):

1T 6W 6W 1T

输出样例:

1T.6W.

输入样例:(和边张)

1T 2T 6B 6B

输出样例:

3T.

输入样例(和卡):

4T 2T 6W 6W

输出样例:

3T.

输入样例(和单吊1张):

4T 2T 6W 3T

输出样例:

6W.

输入样例(和单吊或和卡):

4T 2T 3T 3T

输出样例:

3T.

输入样例(平和、单吊):

4T 4T 4T 3T

输出样例:

2T.3T.5T.

输入样例(没和):

4T 4T 4T 4T

输出样例:

No jiaor

输入样例(没和):

4T 4T 4W 8B

输出样例:

No jiaor

解题思路:

还记得上次写扑克,这次是写麻将,麻将的规则比起扑克要麻烦一些,从题目给出了很多的样例也可以看出

  • 使用结构体对麻将卡牌进行拆分

  • 输出是要按牌型排序的,用一个数组type存储牌型,用序号表示优先级

  • 记住一副牌里一种卡牌只有四张,如果手上卡牌4张一样的话是没法有叫儿的

  • 可以分析一下,一共有4张牌,对于牌型,若三种牌型卡牌分布为1 1 2是不可能有叫儿的,

  • 不论顺序,要有叫儿的话,只有三种牌型分布4 0 0,2 2 0,3 1 0

  • 先分析4 0 0的情况,也就是手上4张牌牌型一样,这种是情况最复杂的,按我写的代码的思路按顺序说情况,
    先是4张牌点数连一起,那可以和的牌只有牌只有两张,中间的不能动,与最小点数或最大点数凑成对子
    三张牌点数连一起,以实例展示吧,比如4T 2T 3T 3T,这种情况只能再给一张与那张对子一样的牌,还有就是4T 2T 3T 7T,与剩下那张凑个对子
    三张卡牌相同,那就要判断剩下那张卡牌与这三张的点数关系,还要判断边界关系,比如 1T 2T 2T 2T,这种卡在边界的,就只有两种,一种自身,还有组成一个顺子,不在边界且差为1,比如4T 4T 4T 3T,除了自身,还可以组两种顺子,还有差为2的,比如4T 4T 4T 2T,一种自身,一种顺子,当差大于2时,就只有自身了

  • 3 1 0的情况,只有那三张牌凑成了顺子或一样的,才行,只有一种就剩下那张牌再来一张才能和

  • 2 2 0的情况,只有两两为对子或一为对子,另两张点数相连才行,若为对子就输出对子的牌,注意按从小到大输出,有对子就只能凑对子了

参考代码:

#include<stdio.h>char type[3] = {'T', 'B', 'W'};//表示牌型优先级
struct node {char model;//牌型int number[10];//存储该牌型对应的点数的牌,比如若有点数为1的牌,则number[1]++int flag;//表示在该牌型有几张牌
} card[3];//三种牌型void print() {//没有叫儿printf("No jiaor");
}void flag_1() {//处理当其他三张牌凑成了顺子或一样时的情况,且牌型与那三张牌不同for (int i = 0; i < 3; i++) {if (card[i].flag == 1) {for (int j = 1; j <= 9; j++) {if (card[i].number[j]) {//找出那张牌,再给一张一样的牌就是一个对子,就和了printf("%d%c.", j, card[i].model);return;}}}}
}int same_card(int i) {//三张牌凑成了顺子或一样的for (int j = 1; j <= 7; j++) {if ((card[i].number[j] && card[i].number[j + 1] && card[i].number[j + 2]) || card[i].number[j] == 3) {flag_1();return 1;}}return 0;
}
int Straight(int i)//4张卡牌顺子
{for(int j=1;j<=6;j++){if(card[i].number[j] && card[i].number[j + 1] && card[i].number[j + 2]&&card[i].number[j + 3]){printf("%d%c.%d%c.",j,card[i].model,j+3,card[i].model);return 1;}}return 0;
}
int _Straight(int i)//三张顺
{int vis[10]={0};int j;for(j=1;j<=7;j++){if((card[i].number[j] && card[i].number[j + 1] && card[i].number[j + 2])){vis[j]=vis[j+1]=vis[j+2]=1;break;}}if(j==8)//j==8意味着没有顺子return 0;for(j=1;j<=9;j++){if(vis[j]&&card[i].number[j]==2)//情况例:4T 2T 3T 3T{printf("%d%c.", j, card[i].model);return 1;}if(!vis[j]&&card[i].number[j]){printf("%d%c.", j, card[i].model);return 1;}}return 0;
}
void same_card_4(int i,int j)
{int k;for(k=1;k<j;k++){if(card[i].number[k]){break;}}if(k<j){if(j-k==1)//情况例:4T 4T 4T 3T{if(k>1)printf("%d%c.",k-1,card[i].model);printf("%d%c.",k,card[i].model);printf("%d%c.",k+2,card[i].model);return;}else if(j-k==2)//情况例:4T 4T 4T 2T{printf("%d%c.",k,card[i].model);printf("%d%c.",k+1,card[i].model);return;}printf("%d%c.",k,card[i].model);//差大于2return;}for(k=j+1;k<=9;k++){if(card[i].number[k]){break;}}if(k<=9){if(k-j==1)//情况例:4T 4T 4T 3T{printf("%d%c.",k-2,card[i].model);printf("%d%c.",k,card[i].model);if(k<9)printf("%d%c.",k+1,card[i].model);return;}else if(j-k==2)//情况例:4T 4T 4T 2T{printf("%d%c.",k-1,card[i].model);printf("%d%c.",k,card[i].model);return;}printf("%d%c.",k,card[i].model);//差大于2return;}
}
void flag_2()
{int count=0;int number_2[2];int Pairs[2]={0};int count_i;int Pairs_i;for(int i=0;i<3;i++){if(card[i].flag==2){for(int j=1;j<=9;j++){if(card[i].number[j]==2){number_2[count++]=j;if(count==2){printf("%d%c.",number_2[0],card[count_i].model);printf("%d%c.",number_2[1],card[i].model);return;}count_i=i;break;}else if(j<9&&card[i].number[j]&&card[i].number[j+1]){if(j>1)Pairs[0]=j-1;if(j<8)Pairs[1]=j+2;Pairs_i=i;break;}else if(j<8&&card[i].number[j]&&card[i].number[j+2]){Pairs[0]=j+1;Pairs_i=i;break;}}}}if(count==1){if(Pairs[0])printf("%d%c.",Pairs[0],card[Pairs_i].model);if(Pairs[1])printf("%d%c.",Pairs[1],card[Pairs_i].model);if(!(Pairs[0]||Pairs[1]))print();return;}print();
}
void solve() {for (int i = 0; i < 3; i++) {if (card[i].flag == 4) {if(Straight(i))return;if(_Straight(i))return;for(int j=1;j<=9;j++){if(card[i].number[j]==3)//三张卡牌相同{same_card_4(i,j);//传入j,从j开始往两头找剩下那张牌,也便于判断剩下那张牌与这三张卡牌的点数关系return;}}}if (card[i].flag == 3) {if(!same_card(i)){print();}return;}}flag_2();
}int main() {for (int i = 0; i < 3; i++)card[i].model = type[i];char model;int number;while (~scanf("%d%c", &number, &model)) {//获取输入的卡牌for (int i = 0; i < 3; i++) {if (card[i].model == model) {card[i].number[number]++;if (card[i].number[number] == 4) {//当有4张卡牌一样时,则不可能有叫儿print();return 0;}card[i].flag++;break;}}}solve();return 0;
}

餐饮服务质量调查打分

任务描述
在商业和科学研究中,人们经常需要对数据进行分析并将结果以直方图的形式显示出来,这会大大增加这些数据的直观性,也便于数据的分析与对比。下面以顾客对餐饮服务打分为例,输入一个正整数repeat (0<repeat<10),做repeat次下列运算:
输入一个正整数n(1≤n≤20),表示有n个学生被邀请来给自助餐厅的食品和服务质量打分,分数划分为1~5这5个等级(1表示最低分,5表示最高分),试统计调查结果,并用*打印出如下形式的统计结果直方图。

输入格式:

第1个整数repeat为数据组数,一共有repeat组数据,请分别处理每组数据,每组数据输出一个直方图。
接下来为repeat组数据,每组数据的第1个数为打分人数n,接下来为这n个人的n个打分。

输出格式:

按输出样例的样式输出结果。

输入样例:

1
10
1 2 2 3 3 5 2 2 3 5

输出样例:

  ** ** *   *
* * *   *
1 2 3 4 5

输入样例:

2
10
1 1 1 1 1 2 3 4 5 5
20
1 1 1 2 2 2 3 3 3 4 5 1 2 3 4 2 2 3 5 2

输出样例:

*
*
*
*       *
* * * * *
1 2 3 4 5*** *
* * *
* * *
* * * * *
* * * * *
1 2 3 4 5

解题思路:

这题比起前面的纸牌游戏就简单不少了,就是画图

  • 仍然是用结构体处理,number和score像构成了坐标一样,嘿嘿

参考代码:

#include<stdio.h>
struct node
{int number;//打该分的人数int score;//分数
}student[6];
int max=0;//打分最多,也就是图里的最高纵坐标
void solve()
{for(int i=max;i>0;i--){int flag=0;//统计图中空的地方int t=0;for(int j=1;j<=5;j++){if(student[j].number>=i){for(int i=0;i<flag;i++){printf("  ");}flag=0;if(t)printf(" ");printf("*");t++;}elseflag++;}printf("\n");}
}
int main()
{int repeat;scanf("%d",&repeat);int n,a;for(int i=1;i<=5;i++){student[i].score=i;}while(repeat--){scanf("%d",&n);for(int i=1;i<=5;i++)student[i].number=0;for(int i=0;i<n;i++){scanf("%d",&a);  for(int j=1;j<=5;j++){if(a==student[j].score){student[j].number++;if(max<student[j].number)max=student[j].number;break;}}}solve();printf("1 2 3 4 5\n");}return 0;
}

月历

任务描述
X想知道某年某月的日历,你能为他编程输出吗?

输入格式:

输入一行,两个正整数,分别代表年份和月份。

输出格式:

严格按样例格式输出一个月的日历。
第1行输出月份简称和年份,中间有个圆点和空格。
第2行输出表头,为星期一至星期日的缩写,每个单词之间一个空格。
第3行为28个减号。
接下来的几行是日历内容,每个日期输出时占3列,日期前后之间再加1个空格,保证与相对应的星期名称右对齐。

输入样例:

2019 9

输出样例:

SEP. 2019
Mon Tue Wed Thu Fri Sat Sun
---------------------------12   3   4   5   6   7   89  10  11  12  13  14  1516  17  18  19  20  21  2223  24  25  26  27  28  2930

提示

重要提示:190011日是星期一。
星期一:Monday 缩写:Mon.
星期二:Tuesday 缩写:Tue.
星期三:Wednesday 缩写:Wed.
星期四:Thursday 缩写:Thu.
星期五:Friday 缩写:Fri.
星期六:Saturday 缩写:Sat.
星期日:Sunday 缩写:Sun.
一月份JAN.
二月份FEB.
三月份MAR.
四月份APR.
五月份MAY.
六月份JUN.
七月份JUL.
八月份AUG.
九月份SEP.
十月份OCT.
十一月份NOV.
十二月份DEC.

解题思路:

还是画图,不过这个感觉有意思些,
不过我一开始没有看到提示里的1900年1月1日是星期一。用了蔡勒公式
蔡勒公式:
int h = (day + 2 * month + 3 * (month + 1) / 5 + year + year / 4 - year / 100 + year / 400 + 1) % 7;
day为日,month为月份,year为年份
h的值是几,即为星期几,
为0时,星期天

参考代码:

使用蔡勒公式版:

//请在此输入你的代码,复杂程序可先在Dev C++中运行调试后再提交
#include<stdio.h>
void print_month(int year,int month)
{switch(month){case 1:printf("JAN. ");break;case 2:printf("FEB. ");break;case 3:printf("MAR. ");break;case 4:printf("APR. ");break;case 5:printf("MAY. ");break;case 6:printf("JUN. ");break;case 7:printf("JUL. ");break;case 8:printf("AUG. ");break;case 9:printf("SEP. ");break;case 10:printf("OCT. ");break;case 11:printf("NOV. ");break;case 12:printf("DEC. ");break;}printf("%d\n",year);
}
void print_week()
{printf("Mon Tue Wed Thu Fri Sat Sun\n");
}
int getWeek(int year,int month,int day)//蔡勒公式
{if(month<3)//如果给定日期在1月或2月(即month1为1或2),则需要将年份减1,将月份增加12。这是为了将这两个月视为前一年的13月和14月{month+=12;year--;}//int h=(sun+(13*(month1+1)/5)+year%100+(year%100/4)+(year/400)-2*(year/100))%7;int h=(day+2*month+3*(month+1)/5+year+year/4-year/100+year/400+1)%7;return h;
}
int main()
{int year,month;scanf("%d%d",&year,&month);print_month(year,month);print_week();for(int i=0;i<27;i++)printf("-");printf("\n");int k=year%100?year%4?0:1:year%400?0:1;int m[13]={0,31,28+k,31,30,31,30,31,31,30,31,30,31};int h=getWeek(year,month,1);int count=h;if(h==0){for(int i=0;i<6;i++)printf("    ");count=7;}for(int i=1;i<h;i++)printf("    ");int t=0;for(int i=1;i<=m[month];i++){if(t)printf(" ");printf("%3d",i);t++;if(count==7){printf("\n");count=0;t=0;}count++;}return 0;
}

利用题目中的提示:

//请在此输入你的代码,复杂程序可先在Dev C++中运行调试后再提交
#include<stdio.h>
void print_month(int year,int month)
{switch(month){case 1:printf("JAN. ");break;case 2:printf("FEB. ");break;case 3:printf("MAR. ");break;case 4:printf("APR. ");break;case 5:printf("MAY. ");break;case 6:printf("JUN. ");break;case 7:printf("JUL. ");break;case 8:printf("AUG. ");break;case 9:printf("SEP. ");break;case 10:printf("OCT. ");break;case 11:printf("NOV. ");break;case 12:printf("DEC. ");break;}printf("%d\n",year);
}
void print_week()
{printf("Mon Tue Wed Thu Fri Sat Sun\n");
}
int getWeek(int year,int month,int day)//蔡勒公式
{if(month<3)//如果给定日期在1月或2月(即month1为1或2),则需要将年份减1,将月份增加12。这是为了将这两个月视为前一年的13月和14月{month+=12;year--;}//int h=(sun+(13*(month1+1)/5)+year%100+(year%100/4)+(year/400)-2*(year/100))%7;int h=(day+2*month+3*(month+1)/5+year+year/4-year/100+year/400+1)%7;return h;
}
int fun(int year)//获取从1900到输入的年份的天数
{int days=0;for (int a = 1900; a < year; a++){if (a % 400 == 0 || a % 4 == 0 && a % 100 != 0){days+=366;}elsedays+=365;}return days;
}
int funweek(int year,int days)//判断星期几
{days+=fun(year);//总天数int h=days%7;return h;
}
int main()
{int year,month;scanf("%d%d",&year,&month);print_month(year,month);print_week();for(int i=0;i<27;i++)printf("-");printf("\n");int k=year%100?year%4?0:1:year%400?0:1;int m[13]={0,31,28+k,31,30,31,30,31,31,30,31,30,31};//int h=getWeek(year,month,1);int days=1;for(int i=1;i<month;i++){days+=m[i];}int h=funweek(year,days);int count=h;if(h==0){for(int i=0;i<6;i++)printf("    ");count=7;}for(int i=1;i<h;i++)printf("    ");int t=0;for(int i=1;i<=m[month];i++){if(t)printf(" ");printf("%3d",i);t++;if(count==7){printf("\n");count=0;t=0;}count++;}return 0;
}

鲜花数

任务描述
鲜花数是指一个N位正整数(7≥N≥3),它的每个位上的数字的N次幂之和等于它本身。
例如:
153=13+53+33 ,1634=14+64+34+44

当N=3时,花朵数又称为水仙花数;

当N=4时,花朵数又称为四叶玫瑰数;

当N=5时,花朵数又称为五角星数;

当N=6时,花朵数又称为六合数;

当N=7时,花朵数又称为北斗数,等等。

要求编写程序,输出所有N位花朵数。

输入格式:

一个整数N(7≥N≥3

输出格式:

从小到大输出所有N位鲜花数,一个数一行。

输入样例:

3

输出样例:

153
370
371
407

输入样例:

4

输出样例:

1634
8208
9474

解题思路:

这题没什么好说的,就是N为几,就去遍历10N-1到10N的数,就是拓展了下那道经典的水仙花的题目

参考代码:

#include <stdio.h>
#include <math.h>// 函数声明,
int isFlower(int number, int N);
void findFlower(int N);int main() {int N;scanf("%d", &N);findFlower(N);return 0;
}// 检查一个数是否为鲜花数
int isFlower(int number, int N) {int originalNumber = number;int sum = 0;while (number > 0) {int digit = number % 10;sum += pow(digit, N);number /= 10;}return sum == originalNumber;
}// 找到并打印所有N位鲜花数
void findFlower(int N) {int lower = pow(10, N - 1);int upper = pow(10, N);for (int i = lower; i < upper; i++) {if (isFlower(i, N)) {printf("%d\n", i);}}
}

这篇关于新形态C语言程序设计游戏化任务教程:第6章17关-20关的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1115723

相关文章

电脑没有仿宋GB2312字体怎么办? 仿宋GB2312字体下载安装及调出来的教程

《电脑没有仿宋GB2312字体怎么办?仿宋GB2312字体下载安装及调出来的教程》仿宋字体gb2312作为一种经典且常用的字体,广泛应用于各种场合,如何在计算机中调出仿宋字体gb2312?本文将为您... 仿宋_GB2312是公文标准字体之一,仿China编程宋是字体名称,GB2312是字php符编码标准名称(简

VScode连接远程Linux服务器环境配置图文教程

《VScode连接远程Linux服务器环境配置图文教程》:本文主要介绍如何安装和配置VSCode,包括安装步骤、环境配置(如汉化包、远程SSH连接)、语言包安装(如C/C++插件)等,文中给出了详... 目录一、安装vscode二、环境配置1.中文汉化包2.安装remote-ssh,用于远程连接2.1安装2

C语言小项目实战之通讯录功能

《C语言小项目实战之通讯录功能》:本文主要介绍如何设计和实现一个简单的通讯录管理系统,包括联系人信息的存储、增加、删除、查找、修改和排序等功能,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录功能介绍:添加联系人模块显示联系人模块删除联系人模块查找联系人模块修改联系人模块排序联系人模块源代码如下

vscode保存代码时自动eslint格式化图文教程

《vscode保存代码时自动eslint格式化图文教程》:本文主要介绍vscode保存代码时自动eslint格式化的相关资料,包括打开设置文件并复制特定内容,文中通过代码介绍的非常详细,需要的朋友... 目录1、点击设置2、选择远程--->点击右上角打开设置3、会弹出settings.json文件,将以下内

基于Go语言实现一个压测工具

《基于Go语言实现一个压测工具》这篇文章主要为大家详细介绍了基于Go语言实现一个简单的压测工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录整体架构通用数据处理模块Http请求响应数据处理Curl参数解析处理客户端模块Http客户端处理Grpc客户端处理Websocket客户端

Window Server创建2台服务器的故障转移群集的图文教程

《WindowServer创建2台服务器的故障转移群集的图文教程》本文主要介绍了在WindowsServer系统上创建一个包含两台成员服务器的故障转移群集,文中通过图文示例介绍的非常详细,对大家的... 目录一、 准备条件二、在ServerB安装故障转移群集三、在ServerC安装故障转移群集,操作与Ser

windos server2022的配置故障转移服务的图文教程

《windosserver2022的配置故障转移服务的图文教程》本文主要介绍了windosserver2022的配置故障转移服务的图文教程,以确保服务和应用程序的连续性和可用性,文中通过图文介绍的非... 目录准备环境:步骤故障转移群集是 Windows Server 2022 中提供的一种功能,用于在多个

使用SQL语言查询多个Excel表格的操作方法

《使用SQL语言查询多个Excel表格的操作方法》本文介绍了如何使用SQL语言查询多个Excel表格,通过将所有Excel表格放入一个.xlsx文件中,并使用pandas和pandasql库进行读取和... 目录如何用SQL语言查询多个Excel表格如何使用sql查询excel内容1. 简介2. 实现思路3

Go语言实现将中文转化为拼音功能

《Go语言实现将中文转化为拼音功能》这篇文章主要为大家详细介绍了Go语言中如何实现将中文转化为拼音功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 有这么一个需求:新用户入职 创建一系列账号比较麻烦,打算通过接口传入姓名进行初始化。想把姓名转化成拼音。因为有些账号即需要中文也需要英

龙蜥操作系统Anolis OS-23.x安装配置图解教程(保姆级)

《龙蜥操作系统AnolisOS-23.x安装配置图解教程(保姆级)》:本文主要介绍了安装和配置AnolisOS23.2系统,包括分区、软件选择、设置root密码、网络配置、主机名设置和禁用SELinux的步骤,详细内容请阅读本文,希望能对你有所帮助... ‌AnolisOS‌是由阿里云推出的开源操作系统,旨