关于coder168E问题的分析与解答(C语言)

 

题目链接在这里噢。不知道在哪戳我》》》https://atcoder.jp/home《《《(之后自行找到coder168beginnertest噢!)

序言:最近发现C语言其实是很有魅力的,实用的指针直截了当,简单粗暴,一下子

就抓住了核心,在进行一些算法的描述上往往比起有更多封装的语言(使用得当的话)可以省下更多的运算时间。看起来简洁而有力。

咳咳!到讲正题的时候了。首先给出官方解答image

解析:稍微解读一下。其实就是将各个沙丁鱼(sardine)的各个指标同除以最大公约数以达到实现各项指标标准化。就不会出现(1,3)(2,6)同时出现的情况,方便进一步的判断,然后再利用链表或是什么东西来将对应的(on bad terms)的沙丁鱼关联起来,这些关系不好的鱼呢就不能同时装进箱子里,那就方便运算了。下面给出代码和注释

#include<stdio.h>
#include<stdlib.h>
long gcd(long a,long b){return b?gcd(b,a%b):a;}
const long mod=1e9+7;
struct X{long A,B;int f;};
struct X A[2<<17];
long long O=mod-1;
int cmp(const void *a,const void *b){
    struct X *aa=(struct X *)a;
    struct X *bb=(struct X *)b;//强制类型转化,指针用法关键
    long dA=aa->A-bb->A,dB=aa->B-bb->B;
    return dA?dA<0?-1:1:dB?dB<0?-1:1:0;//很关键噢,实现排序是进行最后一步运算的关键
}


int main()
{
    int N;long a,b;
    int sz=0;
    scanf("%d",&N);
    ////输入并实现a,b的标准化
    for(int i=0;i<N;i++){
        scanf("%ld %ld",&a,&b);
            int f=0;
        if(!a&&!b) O++;
        else{
              long g=gcd(a,b);
              a=a/g;b=b/g;
            if(a<0){
                a=-a;
                b=-b;
            }
            if(a==0){
                a=1;
                b=0;
                f=1;//f为1表示该项经过翻转成为了和原来项一样的项,与原来项不能并存
            }
            else if(b<0){
                long t;
                t=a;
                a=-b;
                b=t;
                f=1;
            }
            A[sz].A=a;
            A[sz].B=b;
            A[sz].f=f;
            sz++;
        }
    }
    //实现排序
    qsort(A,sz,sizeof(struct X),cmp);
    //实现计算;
    long ans=1;
    for(int i=0;i<sz;){
        int c[2]={1,1};
        int j=i;
        while(i<sz&&A[i].A==A[j].A&&A[i].B==A[j].B){
            c[A[i].f]=c[A[i].f]*2%mod;//排列算法
            i++;
        }
        ans=ans*(c[0]+c[1]-1)%mod;//这里就用到排列组合的知识了,因为相加算了两次,要减掉1
    }
    printf("%d",(ans+O)%mod);
}

关键知识点:qsort的使用 cmp中结构体函数的指向。重点。敲黑板下载明天会更好。

祈祷祈祷

每日赠言:人的欲望很大,不要膨胀,人更会得到幸福。自律的日子很幸福,很充实。

posted @ 2020-05-24 22:41  cry555  阅读(131)  评论(0编辑  收藏  举报