PAT天梯赛L2-028 秀恩爱分得快 c语言 (“-0“)

古人云:秀恩爱,分得快。

互联网上每天都有大量人发布大量照片,我们通过分析这些照片,可以分析人与人之间的亲密度。如果一张照片上出现了 K 个人,这些人两两间的亲密度就被定义为 1/K。任意两个人如果同时出现在若干张照片里,他们之间的亲密度就是所有这些同框照片对应的亲密度之和。下面给定一批照片,请你分析一对给定的情侣,看看他们分别有没有亲密度更高的异性朋友?

输入格式:

输入在第一行给出 2 个正整数:N(不超过1000,为总人数——简单起见,我们把所有人从 0 到 N-1 编号。为了区分性别,我们用编号前的负号表示女性)和 M(不超过1000,为照片总数)。随后 M 行,每行给出一张照片的信息,格式如下:

K P[1] ... P[K]

其中 K(≤ 500)是该照片中出现的人数,P[1] ~ P[K] 就是这些人的编号。最后一行给出一对异性情侣的编号 A 和 B。同行数字以空格分隔。题目保证每个人只有一个性别,并且不会在同一张照片里出现多次。

输出格式:

首先输出 A PA,其中 PA 是与 A 最亲密的异性。如果 PA 不唯一,则按他们编号的绝对值递增输出;然后类似地输出 B PB。但如果 A 和 B 正是彼此亲密度最高的一对,则只输出他们的编号,无论是否还有其他人并列。

输入样例 1:

10 4
4 -1 2 -3 4
4 2 -3 -5 -6
3 2 4 -5
3 -6 0 2
-3 2

输出样例 1:

-3 2
2 -5
2 -6

输入样例 2:

4 4
4 -1 2 -3 0
2 0 -3
2 2 -3
2 -1 2 
-3 2

输出样例 2:

-3 2

  
代码解释:使用的结构体数组进行存储,并且男女分开存的,在遍历时节省时间

第1点是要注意里面有-0 和0 的区别 所以只能用字符串输入,而且字符串的最少为5个空间,因为忽略了这一点,测试点4找了3个小时的错

第2点要注意会有双方亲密值都为0的测试点,这时相当于双方亲密值都是最高的,直接输出一行,但没有只有1方亲密值为0的测试点,代码中也没有考虑这一点

第3点 abs(0.009)==0 ,小数不能用abs,除法时要把总人数变为float型 

 代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
typedef struct node{
    int total;                //总人数
    int boy[500];             //记录照片上的男人
    int girl[500];           //记录照片上的女人
    int boynum;              //代表这张照片里男生人数
    int girlnum;             //代表女生人数
    int flag;                 //记录这张照片有没有男女主角
}ONE;
void FindPAPB(ONE photo[],int sexa,int sexb,int PA,int PB);
void updateFlag(int sex,ONE photo[],int i);
void FindGroupPhoto(int sex,ONE photo[],int *maxloc,float *Intimacy,float GroupPhoto[]);
void FindMaxLoc(int maxloc,float Intimacy,float GroupPhoto[],int loc[],int *top,int *flag,int P);

int n,m;                //n总人数 m照片数量
int main()
{
    scanf("%d%d",&n,&m);
    ONE photo[m];int temp;
    for (int i=0;i<m;i++) //初始化
    {
        photo[i].total=0;
        photo[i].girlnum=0;
        photo[i].boynum=0;
        photo[i].flag=0;
    }
    char str[10];
    for (int i=0;i<m;i++)
    {
        scanf("%d\n",&(photo[i].total));
        for (int j=0;j<photo[i].total;j++)
        {
            scanf("%s",str);        //!!!!!有-0 和 0 必须用字符串区分
            temp=atoi(str);
            if (!strcmp(str,"-0") || temp<0)
                photo[i].girl[photo[i].girlnum++]=temp;
            else
                photo[i].boy[photo[i].boynum++]=temp;
        }
    }
    //输入男女主角 并标志为男女
    char stra[5],strb[5];scanf("%s %s",stra,strb);//!!!!!!字符串长度最少为5 否则测试点4错误 
    int PA=atoi(stra),PB=atoi(strb),sexa=0,sexb=0; //-1代表女 1代表男
    if (!strcmp(stra,"-0") || PA<0)
        sexa--;
    else
        sexa++;
    if (!strcmp(strb,"-0") || PB<0)
       sexb--;
    else
        sexb++;
    
    FindPAPB(photo,sexa,sexb,PA,PB);            //找照片里是否有男女主角
    //GroupPhotoA GroupPhotoB数组下表代表合照的人的绝对值 里面的数代表亲密值
    float GroupPhotoA[1001]={0},GroupPhotoB[1001]={0}; 
    int maxlocA=0,maxlocB=0;                            //maxlocA为数组达到的最大下标 用于循环 节省时间
    float IntimacyA=0,IntimacyB=0;                        //IntimacyA记录最大亲密值
    FindGroupPhoto(sexa,photo,&maxlocA, &IntimacyA, GroupPhotoA );
    FindGroupPhoto(sexb,photo,&maxlocB, &IntimacyB, GroupPhotoB );
   //flag是0代表双方亲密值都没有最大 1代表某一个人亲密值最大 2代表双方亲密值都最大
    int flag=0;                                      
    int locA[maxlocA],locB[maxlocB],topA=0,topB=0;    //找照片里面达到最大亲密值的并记录在locA、locB数组里面 记录着最大的位置
    FindMaxLoc(maxlocA,IntimacyA,GroupPhotoA,locA,&topA,&flag,PB);
    FindMaxLoc(maxlocB,IntimacyB,GroupPhotoB,locB,&topB,&flag,PA);
    
    //输出 !!!!!! 测试点里面没有只有其中1方最大亲密值为0的 只有测试点3两方亲密值都为0
    if (flag==2 || (!IntimacyA && !IntimacyB))    //如果 A 和 B 正是彼此亲密度最高的一对 或者 !!!!!1张照片也没有(测试点3) 只输出这一对
        printf("%s %s\n",stra,strb);
    else                                    //如果AB不是彼此亲密值最大的一对 则输出亲密值最大的所有人
    {
        for (int i=0;i<topA;i++)
        {
            if (sexa<0 )
                printf("%s %d\n",stra,locA[i]);//直接由stra输出 不用再分-0的情况
            else
                printf("%s -%d\n",stra,locA[i]);
        }
        for (int i=0;i<topB;i++)
        {
            if (sexb<0  )
                printf("%s %d\n",strb,locB[i]);
            else 
                printf("%s -%d\n",strb,locB[i]);
        }
    }
}

/*!!!!!输入  测试点3类似
10 0
-0 1
输出
-0 1*/
 //找照片里有没有男女主角
void FindPAPB(ONE photo[],int sexa,int sexb,int PA,int PB) 
{
    for (int i=0;i<m;i++)                 //标志如果只有该女的标志为-1 只有该男的标志为1 都有标志为2
    {
        for (int j=0;j<photo[i].girlnum;j++)
        {
            if (sexa<0 && PA==photo[i].girl[j] )  //a是女的并且照片里有
                updateFlag(sexa,photo,i);    
            else if(sexb<0 && PB==photo[i].girl[j])    //b是女的并且照片里有
                updateFlag(sexb,photo,i);
        }
        for (int j=0;j<photo[i].boynum;j++)
        {
             if(sexa>0 && PA==photo[i].boy[j])
                updateFlag(sexa,photo,i);
             else if(sexb>0 && PB==photo[i].boy[j])
               updateFlag(sexb,photo,i);
        }
    }
}
//更新结构体里的flag 如果为1代表有男主角 -1代表女主角 2代表都有
void updateFlag(int sex,ONE photo[],int i)
{
    if(photo[i].flag)            //如果已经有其中一个了
    {
        photo[i].flag=2;
        return;
    }
    if (sex<0)
        photo[i].flag=-1;
    else
        photo[i].flag=1;
}
//找合照的人
void FindGroupPhoto(int sex,ONE photo[],int *maxloc,float *Intimacy,float GroupPhoto[])
{
    for (int i=0;i<m;i++)                    
    {
        if (sex>0)                        //如果是男的 找女的
        {
            if (!(photo[i].flag==1 || photo[i].flag==2))//如果这张照片没有这男的
                continue;
            for (int j=0;j<photo[i].girlnum;j++)
            {
                GroupPhoto[abs(photo[i].girl[j])]+=(1/(float)photo[i].total);//必须有float
                if (abs(photo[i].girl[j]) > *maxloc)        //maxloc记录GroupPhoto的最大下标 访问时节省时间
                    *maxloc = abs(photo[i].girl[j]);
                if (GroupPhoto[abs(photo[i].girl[j])] > *Intimacy)        //Intimacy记录最大亲密值
                    *Intimacy = GroupPhoto[abs(photo[i].girl[j])];      //不能加abs abs(0.009)=0  //printf("\n%f",abs(0.09));
            }
        }
        else            //如果是女的
        {
             if(!(photo[i].flag==-1 || photo[i].flag==2))//  只有1或0时才中断  或者if (photo[i].flag!=-1 && photo[i].flag!=2)也对
                continue;
            for (int j=0;j<photo[i].boynum;j++)
            {
                GroupPhoto[photo[i].boy[j]]+=(1/(float)photo[i].total);
                if (abs(photo[i].boy[j]) > *maxloc)
                    *maxloc = abs(photo[i].boy[j]);
                if (GroupPhoto[photo[i].boy[j]] > *Intimacy)
                    *Intimacy = GroupPhoto[photo[i].boy[j]];
            }
        }
    }
}//找照片里面达到最大亲密值的并记录在locA、locB数组里面 记录着最大的位置
void FindMaxLoc(int maxloc,float Intimacy,float GroupPhoto[],int loc[],int *top,int *flag,int P)
{
    for (int i=0;i<=maxloc && Intimacy;i++)  //亲密值不能为0 因为GroupPhoto数组的初值全为0
    {
        if (GroupPhoto[i]==Intimacy)
        {
            loc[(*top)++]=i;    //必须加()
            if (i==P || i==-P)
                (*flag)++;
        }
    }
}



根据提供的引用内容,这段代码是用来统计输入数字中奇数和偶数的个数的。代码中使用循环遍历输入的数字,通过对2取模运算来判断数字是奇数还是偶数,然后分别对奇数和偶数的计数变量进行加一操作。循环结束后,输出奇数计数变量和偶数计数变量的值,中间用空格隔开。\[1\]\[2\]\[3\] 这段代码可以用来解决团体程序设计天梯赛-练习集 L1-022 奇偶分家的问题。 #### 引用[.reference_title] - *1* [PTA团队天梯赛║L1-022 奇偶分家](https://blog.csdn.net/m0_46492118/article/details/114481127)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [PAT团队程序设计天梯赛-习题集L1-022 奇偶分家](https://blog.csdn.net/qq_38234015/article/details/81291913)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [团体程序设计天梯赛-练习集 L1-022 奇偶分家 (10分)(C语言)](https://blog.csdn.net/Baridhu/article/details/109899606)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值