徐凤年606 2021-09-09 14:42 采纳率: 100%
浏览 71
已结题

这个问题是需要改排序算法吗,显示运行超时其他的没错

小诺诺喜欢玩纸牌比大小的游戏。现在有一副牌中的若干张纸牌,需要按牌面的数字从大到小的顺序排列,若数字大小相同则按花色从大到小(黑桃>红桃>梅花>方块)排列。牌面为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

img


以下为代码
#include<stdio.h>
#include<stdlib.h>
typedef struct {
char r[10];
int x;
int f;
}Card;
Card card[100];
char ap[100];
int main(){
int l=0;
int T;

scanf("%d",&T);
getchar();
while(T--){
char e='a';
l=0;
while(e!='\n'){

scanf("%s%d",&card[l].r,&card[l].x);
l++;
e=getchar();
}
for(int n=0;n<l;n++){
    
        if(card[n].r[0]=='h')
        card[n].f =3;
        if(card[n].r[0]=='s')
        card[n].f =4;
        if(card[n].r[2]=='u')
        card[n].f =2;
        if(card[n].r[1]=='i')
        card[n].f =1;
    
}
    
Card t;
 for(int i=0;i<l;i++)
        for(int j=0;j<l-1-i;j++)
        {
        
            if(card[j].x<card[j+1].x){
                t=card[j];
                card[j]=card[j+1];
                card[j+1]=t;
            }
            if(card[j].x==card[j+1].x)
                if(card[j].f<card[j+1].f){
                t=card[j];
                card[j]=card[j+1];
                card[j+1]=t;
            }
            }
for(int i=0;i<l;i++)
        printf("%s %d  ",card[i].r,card[i].x );
        printf("\n");
        

}

}

  • 写回答

3条回答 默认 最新

  • Admini$trat0r .net领域新星创作者 2021-09-09 14:43
    关注
    
    #include<stdio.h>
    #include<string.h>
    int main()
    {
        //存储并接收组数
        int a;
        scanf("%d",&a);
        
        //吃数字后面的回车
        //但凡以后遇见数字回车,字符,一定要加上getchar,否则计算机会把数字后面的回车当做字符处理
        getchar();
        
        //循环输入每组牌
        for(int i=0;i<a;i++)
        {
            //存储每组牌
            //小编觉得要将每组牌存储在一个大数组中
            //因为题干有提示首尾有若干空格
            //所以我觉得scanf("%s %d",char*_,int_)这种格式可能接收不到末尾的空格
            //哪怕后面加上getchar也只能接受一个空格,而空格的数量是不确定的
            //导致空格或者回车可能会存储到下一组的字符数组里面,这样的程序肯定错误
            char b[1001];
            
            //接收牌
            gets(b);
            
            //存储牌的数量
            int c=0;
            
            //存储牌的花色
            char d[500][20];
            
            //存储牌的大小
            int e[500]={0};
            
            //控制d数组每个花色字符串的结束
            int k=0;
            
            //将大数组牌的花色和大小分别存储到两个数组中
            for(int j=0;j<strlen(b);j++)
            {
                //判断是否是字母,如果是,存储到d数组中,以空格为标志结束
                if(b[j]>='a'&&b[j]<='z')
                {
                    //第一维控制每个花色
                    //第二位控制每个花色的字母
                    d[c][k++]=b[j];
                    
                    //如果该字母后面是空格,证明本花色字符串结束
                    if(b[j+1]==' ')
                    {
                        //结束每个花色,字符串以'\0'作为结束标志
                        d[c][k]='\0';
                        
                        //将k赋值0,准备接收下一个花色
                        k=0;
                        
                        //小编这种字符串也有些不确定,打印出来看一下前面程序的正确性
                        //printf("%s ",d[c]);
                    }
                }
                
                //判断是否是数字
                else if(b[j]>='0'&&b[j]<='9')
                {
                    e[c]=e[c]*10+b[j]-'0';
                    
                    //如果改数字后面是'\0'或者' '说明数字结束
                    //将控制第一维的变量c加一
                    //准备接收下一个牌的花色和大小
                    //d数组和e数组的角标相互对应
                    if(b[j+1]=='\0'||b[j+1]==' ')
                    {
                        //同样,打印一下,看一下效果,校验前面代码是否符合要求
                        //printf("%d\n",e[c]);
                        c++;
                    }
                }
            }
            
            //上面代码执行完毕,说明花色和大小已经分别存储在两个数组中
            //进行下一步,排序
            for(int j=0;j<c;j++)
            {
                for(int k=j+1;k<c;k++)
                {
                    //作为交换时的中间变量
                    char tp[20];
                    
                    //先比较大小,如果前面的牌比后面的小,调换一下位置
                    if(e[j]<e[k])
                    {
                        //先交换大小
                        int temp=e[j];
                        e[j]=e[k];
                        e[k]=temp;
                        
                        //因为d数组存储的花色和e数组存储的大小的角标是相互对应的
                        //d数组也要进行交换
                        //因为d数组里面是字符串
                        //所以要用字符串复制的函数strcpy
                        //如果用赋值即“=”程序报错
                        strcpy(tp,d[j]);
                        strcpy(d[j],d[k]);
                        strcpy(d[k],tp);
                    }
                    
                    //大小相同,比较花色
                    else if(e[j]==e[k])
                        
                        //因为每个花色的首字母不同,所以我们可以根据首字母判断花色
                        //如果前一张牌的花色是‘d’,则一定小于后一张牌的花色,交换花色
                        //如果后一张牌的花色是‘s’,则一定大于前一张牌的花色,交换花色
                        //如果前一张牌的花色是‘c’,后一张牌的花色是‘h’
                        //前一张牌的花色小于后一张牌的花色,交换花色
                        //就这三种情况,如果花色不是‘d’和‘s’,那就只能是‘c’和‘h’
                        //同理,如果有一个是‘c’,另一个不是‘h’,则一定是‘d’或‘s’
                        //其他情况则无需交换花色
                        if(d[j][0]=='d'||d[k][0]=='s'||(d[j][0]=='c'&&d[k][0]=='h'))
                        {
                            //同理,利用函数交换字符串
                            strcpy(tp,d[j]);
                            strcpy(d[j],d[k]);
                            strcpy(d[k],tp);
                        }
                }
            }
            
            //打印,因为结尾没有空格,所以只打印到倒数第二个
            for(int j=0;j<c-1;j++)
                printf("%s %d ",d[j],e[j]);
            
            //打印最后一个,并换行
            printf("%s %d\n",d[c-1],e[c-1]);
        }
        
        return 0;
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 9月23日
  • 已采纳回答 9月15日
  • 创建了问题 9月9日

悬赏问题

  • ¥15 树莓派与pix飞控通信
  • ¥15 自动转发微信群信息到另外一个微信群
  • ¥15 outlook无法配置成功
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题