代码小总结

来源:互联网 发布:电气火灾监控软件 编辑:程序博客网 时间:2024/06/11 01:45

专题一:数学

1) 闰年判断: year%4==0 && year%100!=0 || year%400==0

2) 九余数定理:一个数的各位数字之和除以9得到的余数

=这个数除以9得到的余数。

3) 快速幂运算 X^n%(mod)的值  <X的n次幂对mod求余>

代码:

int KSM(int X,int n,int mod){  //复杂度O(logn)    int sum=1;  X%=mod;    while(n){          if(n&1)sum=(sum*X)%mod;          X=X*X%mod;          n>>=1;      }      return sum;  }  

4) 辗转相除法:求a b的最大公因数->复杂度O(log(max(a,b)))

A>非递归:

int gcd(int x,int y){  int a; if(!y)return x;    while(a=x%y) (x=y)&&(y=a);     return y;  }  

B>递归

int gcd(int x,int y){    return y?gcd(y,x%y):x;}

欧拉函数

# include <stdio.h># define N 201int E[N];void EOL(){int i=-1,j,k;while(++i<N)E[i]=i;    for(i=2;i<N;i++)if(E[i]==i)for(j=i,k=i-1;j<N;j+=i)E[j]=E[j]/i*k;}int main(){  int i;EOL();for(i=1;i<N;i++)printf("%d %d\n",i,E[i]);return 0;}     

集合归类
运行时限: 1000 ms   单次运行时限: 1000 ms   内存限制: 32 MB
总提交: 1次   通过: 1次

题目描述

对于正整数集合S={1,2,3,4,5,6,7,8,9,10,11,12,13,……,1000000},挑选出S中互异的两个元素X,Y 做运算 X≡Y,表示X与Y属于同一个集合。

例如依次读入三个等价对   1≡5,2≡3,5≡8。

等价对中的数属于同一个集合,我们得到两个集合{1,5,8}和{2,3}这两组集合。

现在需要你编程实现集合的归类。

程序输入说明

第一行 输入N,1<=N<=1000 表示N组数据
第二行至第N+1行 输入两个互异的正整数 X,Y 中间空格隔开,表示X≡Y 1<=X,Y<=1000000。

程序输出说明

输出每个集合 按从小到大输出每个集合的元素
集合按字典序输出

程序输入样例

可见格式带空格和换行符的格式带空格和换行符的格式说明
样例一:61000000 900000900000 800000800000 700000600000 500000400000 600000200000 1000000样例二:111 99998888 99997777 10000001 4564548 4591000000 5555578 8985 5489 4646 54 54 85

代码C:

# include <stdio.h> //用优先队列 时间开销小       # define N 1000001     # define M 10001   void insert(int Tree[],int X);//向堆中插入值 S[WEI]       int Delmin(int Tree[]);       //删除堆头-并返回堆头     int find(int x);    void Link(int x,int y);    int tree[M+1];  //堆      int p[N],Q[M],C[M],T;       int main(){        int i,j,k,l,m,n;      //freopen("AAA.txt","r",stdin);//freopen("BBB.txt","w",stdout);    scanf("%d",&n);        for(i=0;i<n;i++)        {            scanf("%d%d",&j,&k);             if(find(j)!=find(k))                Link(j,k);         }        n=0;        while(tree[0])Q[n++]=Delmin(tree);        for(i=m=0;i<n;i++)            if(p[Q[i]])            {                for(j=i,k=0,l=find(Q[i]);j<n;j++)                    if(p[Q[j]]&&find(Q[j])==l)                    {                        C[k++]=Q[j];                        printf("%d ",Q[j]);                    }                    while(k--)p[C[k]]=0;                    printf("\n");            }            return 0;    }    void insert(int Tree[],int X)//向最小堆中插入X     {              int par,i=++Tree[0];            //插入X 后 Tree[0]+1              while(i>1)                      //直到i不是根节点              {                  par=(i>>1);                 //父节点为par                  if(Tree[par]<=X) break;     //将<=改为>=即改为最大堆了              Tree[i]=Tree[par];          //否则调整堆 即位置上移                  i=par;              }              Tree[i]=X;                      //插入新节点          }          int Delmin(int Tree[])          {              int i=1,L=2,root=Tree[1],X=Tree[Tree[0]--];             while(L<=Tree[0])              {                      L+=L<Tree[0]&&Tree[L+1]<Tree[L];            if(Tree[L]>=X) break;            Tree[i]=Tree[L];                 i=L;    L=i<<1;         }              Tree[i]=X;          return  root;          }    int find(int x)    {        if(!p[x])       {  p[x]=x;    insert(tree,x);//进堆      }      while(x!=p[x]) x=p[x];        return x;    }    void Link(int x,int y)    {        int fx=0,fy=0;        if(!p[x]) p[x]=x;        if(!p[y]) p[y]=y;        while(x!=p[x]&&++fx) x=p[x];        while(y!=p[y]&&++fy) y=p[y];        if(x==y)return ;        if(fx<fy)p[x]=y;        else    p[y]=x;    }