题目链接在这里噢。不知道在哪戳我》》》https://atcoder.jp/home《《《(之后自行找到coder168beginnertest噢!)
序言:最近发现C语言其实是很有魅力的,实用的指针直截了当,简单粗暴,一下子
就抓住了核心,在进行一些算法的描述上往往比起有更多封装的语言(使用得当的话)可以省下更多的运算时间。看起来简洁而有力。
#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中结构体函数的指向。重点。敲黑板明天会更好。