C程序设计专题-作业2

三道题目均需60-80行代码完成,注释非常详细,参考价值高。

7-1 节约有理 (10 分)

小明准备考研,要买一些书,虽然每个书店都有他想买的所有图书,但不同书店的不同书籍打的折扣可能各不相同,因此价格也可能各不相同。因为资金所限,小明想知道不同书店价格最便宜的图书各有多少本,以便节约资金。

输入格式:

首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。 对于每组测试,第一行先输入2个整数m,n(1≤m,n≤100),表示想要在m个书店买n本书;第二行输入m个店名(长度都不超过20,并且只包含小写字母),店名之间以一个空格分隔;接下来输入m行数据,表示各个书店的售书信息,每行由小数位数不超过2位的n个实数组成,代表对应的第1至第n本书的价格。

输出格式:

对于每组测试数据,按要求输出m行,分别代表每个书店的店名和能够提供的最廉价图书的数量,店名和数量之间留一空格。当然,比较必须是在相同的图书之间才可以进行,并列的情况也算。 输出要求按最廉价图书的数量cnt从大到小的顺序排列,若cnt相同则按店名的ASCII码升序输出。

输入样例:

2
3 3
xiwangshop kehaishop xinhuashop
11.1 22.2 33.3
11.2 22.2 33.2
10.9 22.3 33.1
5 5
xwsd khsd xhsd xxsw hytss
1 2 3 4 5
1.2 2.1 2.7 4.1 4.8
0.8 1.9 3.1 3.8 5.2
0.9 1.95 2.65 3.8 5.1
0.9 1.95 2.65 3.8 5.1

输出样例:

xinhuashop 2
kehaishop 1
xiwangshop 1
xhsd 3
hytss 2
xxsw 2
khsd 1
xwsd 0

思路详细分析与代码实现:

int main()
{
    int t;
    scanf("%d",&t);
    char name[100][20];//name表示店名
    double price[100][100];//price存储书籍价格
    double min;//min存储每种书籍的最低价格
    int amount[100];//amount存储各个书店提供的最廉价书目的数量
    while(t--)//t表示测试数据的组数
    {
        int m,n,i,j;//i,j为循环变量
        //amount初始化
        for(i=0;i<=99;i++)
        {
            amount[i]=0;
        }
        scanf("%d %d",&m,&n);//m个书店买n本书
        getchar();
        //读取书店名字
        for(i=0;i<=m-1;i++)
        {
            scanf("%s",name[i]);
        }
        //读取各个书店的书目价格
        for(i=0;i<=m-1;i++)
        {
            for(j=0;j<=n-1;j++)
            {
                scanf("%lf",&price[i][j]);
            }
        }
        //判别每本书籍的最低价格,以及对应的商店
        for(j=0;j<=n-1;j++)
        {
            //先找最低价格
            min=price[0][j];
            for(i=1;i<=m-1;i++)
            {
                if(price[i][j]<min)
                    min=price[i][j];
            }
            //再对应到相关书店,统计廉价书籍的书目
            for(i=0;i<=m-1;i++)
            {
                if(fabs(price[i][j]-min)<=0.001)
                    amount[i]+=1;
            }
        }
        //sorting
        char temp[10];int p;
        for(i=0;i<=m-1;i++)
        {
            for(j=i+1;j<=m-1;j++)
            {
                if(amount[i]<amount[j]||amount[i]==amount[j]&&strcmp(name[i],name[j])>0)
                {
                    p=amount[i];amount[i]=amount[j];amount[j]=p;
                    strcpy(temp,name[i]);strcpy(name[i],name[j]);strcpy(name[j],temp);
                }
            }
        }
        //输出书店和廉价书目数量
        for(i=0;i<=m-1;i++)
        {
            printf("%s %d\n",name[i],amount[i]);
        }
    }
    return 0;
}

7-2 纸牌排序 (10 分)

小诺诺喜欢玩纸牌比大小的游戏。现在有一副牌中的若干张纸牌,需要按牌面的数字从大到小的顺序排列,若数字大小相同则按花色从大到小(黑桃>红桃>梅花>方块)排列。牌面为A、J、Q、K分别用1、11、12、13表示;花色中的黑桃、红桃、梅花、方块分别用英文单词"spade"、"heart"、"club"、"diamond"表示。

输入格式:

测试数据有多组,首先输入测试的组数T (0<T<10),然后是T组测试数据;每组测试输入一行,按“花色 数字”的格式输入若干张牌,花色可能为"spade"、"heart"、"club"、"diamond"之一,数字为1~13。输入的数据之间可能有若干(至少1个)空格,在行的首尾也可能有若干空格,但每组输入数据的总长度不会超过1000个字符。

输出格式:

每组测试输出一行,按描述中的排序规则从大到小输出牌的信息,数据之间都以一个空格分隔。

输入样例:

2
 diamond 1 club 1  heart 1  spade 3 diamond 2 club 3 heart 2  
diamond 13 club 13 heart 13    spade 12

输出样例:

spade 3 club 3 heart 2 diamond 2 heart 1 club 1 diamond 1
heart 13 club 13 diamond 13 spade 12

思路详细分析与代码实现:

//数据输出函数
void printdata(double n)
{
	int integer =(int)(n);
	double fraction = n - integer;
	if (fabs(fraction - 0.8) <= 0.01)printf("spade");
	if (fabs(fraction - 0.6) <= 0.01)printf("heart");
	if (fabs(fraction- 0.4) <= 0.01)printf("club");
	if (fabs(fraction- 0.2) <= 0.01)printf("diamond");
	printf(" %d", integer);
	return;
}
int main()
{
	int t,index; scanf("%d", &t);
    getchar();
	double total[200];
	char color[10]; int number;
	while (t--)//t是测试数据的组数
	{
		char c;
		index = 0;
		while (1)//大循环:读取空格-读取类型和大小-读取空格......终止条件是读取\n
		{
			//读取空格(类型的首字母也存放在c中)
			while (1)
			{
				c = getchar();
				if (c != ' ')
					break;
			}
			//终止条件
			if (c == '\n')
				break;
			//读取类型与大小,用小数赋值的方法区别类型
			scanf("%s %d", color, &number);
			if (strcmp(color, "pade") == 0)
				total[index] =0.8+number;
			if (strcmp(color, "eart") == 0)
				total[index] =0.6+number;
			if (strcmp(color, "lub") == 0)
				total[index] =0.4+number;
			if (strcmp(color, "iamond") == 0)
				total[index] =0.2+number;
			index++;
		}
		//排序(降序)
		double temp;
		int i, j;
		for (i = 0; i <= index-1; i++)
		{
			for (j = i + 1; j <= index - 1; j++)
			{
				if (total[i]<total[j])
				{
					temp = total[i];
					total[i] = total[j];
					total[j] = temp;
				}
			}
		}
		//输出数据
		for (i = 0; i <= index - 1; i++)
        {
			printdata(total[i]);
            if(i<=index-2)
                printf(" ");
        }
		printf("\n");
	}
	return 0;
}

7-3 学车费用 (10 分)

小明学开车后,才发现他的教练对不同的学员收取不同的费用。 小明想分别对他所了解到的学车同学的各项费用进行累加求出总费用,然后按下面的排序规则排序并输出,以便了解教练的收费情况。排序规则: 先按总费用从多到少排序,若总费用相同则按姓名的ASCII码序从小到大排序,若总费用相同而且姓名也相同则按编号(即输入时的顺序号,从1开始编)从小到大排序。

输入格式:

测试数据有多组,处理到文件尾。每组测试数据先输入一个正整数n(n≤20),然后是n行输入,第i行先输入第i个人的姓名(长度不超过10个字符,且只包含大小写英文字母),然后再输入若干个整数(不超过10个),表示第i个人的各项费用,数据之间都以一个空格分隔,第i行输入的编号为i。输入数据和结果均在32位int型范围之内。

输出格式:

对于每组测试,在按描述中要求的排序规则进行排序后,按顺序逐行输出每个人费用情况,包括:费用排名(从1开始,费用相同则排名也相同)、编号、姓名、总费用。每行输出的数据之间留1个空格。

输入样例:

3
Tom 2800 900 2000 500 600
Jack 3800 400 1500 300
Tom 6700 100

输出样例:

1 1 Tom 6800
1 3 Tom 6800
3 2 Jack 6000

思路详细分析与代码实现:
 

typedef struct data
{
	int range;//排名
	int number;//序号
	char name[10];//名字
	int fare;//费用
}data;
int main()
{
	int k, i, j;
	while (scanf("%d",&k)!=-1)
	{
		data stuff[20], temp;
		char c;
		int sum, single;//sum记录费用总和;single是单项费用
		for (i = 0; i <= k - 1; i++)
		{
			sum = 0; single = 0;
			stuff[i].number = i + 1;
			scanf("%s", stuff[i].name);
			//计算每个人费用之和
			c = getchar();
			while (c != '\n')
			{
				c = getchar();
				if (c == ' ' || c == '\n')
				{
					sum += single;
					single = 0;
				}
				if ('0' <= c && c <= '9')
				{
					single = single * 10 + (int)c - '0';
				}
			}
			stuff[i].fare = sum;
		}
		//排序第一步:先交换次序,
		//目的:使费用降序排列,并且排名相同时按照ASCII码值从小到大排序
		for (i = 0; i <= k - 1; i++)
		{
			for (j = i + 1; j <= k - 1; j++)
			{
				if (stuff[i].fare < stuff[j].fare)
				{
					temp = stuff[i]; stuff[i] = stuff[j]; stuff[j] = temp;
				}
				if (stuff[i].fare == stuff[j].fare && strcmp(stuff[i].name, stuff[j].name) > 0)
				{
					temp = stuff[i]; stuff[i] = stuff[j]; stuff[j] = temp;
				}
                if(stuff[i].fare == stuff[j].fare && strcmp(stuff[i].name, stuff[j].name) ==0&&stuff[i].number>stuff[j].number)
                {
                    temp = stuff[i]; stuff[i] = stuff[j]; stuff[j] = temp;
                }
			}
		}
		//排序第二步:再标注序号:注意费用相同时排名相同
		//第一人排名1,之后的人:如果与前一位的人费用相同,则其排序也与前一个人相同;否则他的排名是自身序号。
		stuff[0].range = 1;
		for (i = 1; i <= k - 1; i++)
		{
			if (stuff[i].fare == stuff[i - 1].fare)
				stuff[i].range = stuff[i - 1].range;
			else
				stuff[i].range = i + 1;
		}
		//输出结果
		for (i = 0; i <= k - 1; i++)
		{
			printf("%d %d %s %d\n", stuff[i].range, stuff[i].number, stuff[i].name, stuff[i].fare);
		}
	}
	return 0;
}

  • 10
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大观居士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值