精华内容
下载资源
问答
  • 从一个取值范围为1~N的不重复数列中找出所有满足两数和为N+1的数 题目:一个整数数列,元素取值可能是1~N(N是一个较大的正整数)中的任意一个数,相同数值不会重复出现。设计一个算法,找出数列中符合条件的...

    转载:http://blog.csdn.net/wcyoot/article/details/6436304


    从一个取值范围为1~N的不重复数列中找出所有满足两数和为N+1的数对


    题目:一个整数数列,元素取值可能是1~N(N是一个较大的正整数)中的任意一个数,相同数值不会重复出现。设计一个算法,找出数列中符合条件的数对的个数,满足数对中两数的和等于N+1。复杂度最好是O(n),如果是O(n2)则不得分。

     


    算法:建立一个map<数列元素值, 对应索引>. 对每个元素i,如果N+1-i不在map中,插入i,否则输出(i, map[i]).复杂度O(n).

     

    #include <map>
    // ar为不重复的数列,输出ar中所有两数和为N的数对
    void PrintPairs(const std::vector<int>& ar, int N)
    {
    	std::map<int, int> nodemap; // <数值,位置>
    	for(size_t i = 0; i < ar.size(); ++i)
    	{
    		std::map<int, int>::const_iterator iter = nodemap.find(N - ar[i]);
    		if(iter == nodemap.end())
    			nodemap[ar[i]] = i;
    		else
    		{
    			printf("找到数对(%d, %d)/n", ar[iter->second], ar[i]);
    		}
    	}
    }

    展开全文
  • 设计一个算法,找出数列中符合条件对的个数,满足数中两数和等于N+1。复杂度最好是O(n),如果是O(n2)则不得分。   算法:建立一个map. 每个元素i,如果N+1-i不在map中,插入i,否则输出(i, map...

    题目:一个整数数列,元素取值可能是1~N(N是一个较大的正整数)中的任意一个数,相同数值不会重复出现。设计一个算法,找出数列中符合条件的数对的个数,满足数对中两数的和等于N+1。复杂度最好是O(n),如果是O(n2)则不得分。

     


    算法:建立一个map<数列元素值, 对应索引>. 对每个元素i,如果N+1-i不在map中,插入i,否则输出(i, map[i]).复杂度O(n).

     

    1. #include <map>  
    2. // ar为不重复的数列,输出ar中所有两数和为N的数对  
    3. void PrintPairs(const std::vector<int>& ar, int N)  
    4. {  
    5.     std::map<intint> nodemap;  
    6.     for(size_t i = 0; i < ar.size(); ++i)  
    7.     {  
    8.         std::map<intint>::const_iterator iter = nodemap.find(N - ar[i]);  
    9.         if(iter == nodemap.end())  
    10.             nodemap[i] = ar[i];  
    11.         else  
    12.         {  
    13.             printf("找到数对(%d, %d)/n", ar[iter->second], ar[i]);  
    14.         }  
    15.     }  
    16. }  
     

     

    PS:可参考:http://blog.csdn.net/wcyoot/archive/2011/05/21/6435904.aspx

    展开全文
  • 一个整数数组,元素取值...设计一个算法,找出数列中符合条件对的个数,满足数中两数和等于N+1; 代码#include void FixedSum(int* a,int n,int d){ for(int i = 0,j = n-1;i<n&&j>=0&&i;){ if(a[i]+a[j])

    一个整数数组,元素取值范围可能是1~N中的任意一个数,相同数值不会重复出现。设计一个算法,找出数列中符合条件的数对的个数,满足数对中两数的和等于N+1;
    代码

    #include <stdio.h>
    void FixedSum(int* a,int n,int d){
        for(int i = 0,j = n-1;i<n&&j>=0&&i<j;){
            if(a[i]+a[j]<d)
                ++i;
            else if(a[i]+a[j]>d)
                --j;
            else if(a[i]+a[j]==d){
                printf("%d,%d\n",a[i],a[j]);
                ++i;
                --j;
            }
        }
    }
    int main(){
        int array[] ={1,2,3,4,5};
        int len = sizeof(array)/sizeof(array[0]);
        FixedSum(array,len,6);   //1,5   2,4
        return 0;
    }       
    展开全文
  • 我们可以找到两个长度为N的数列,使得从两个数列中各自挑选一个数相交得出的N^2个数正好是1到N^2之间的所有整数。 对于正样的数列,如果我们将其中一个数列中所有数都加上一个常数,另外一个数列中所有数都减去一个...

    我们可以找到两个长度为N的数列,使得从两个数列中各自挑选一个数相交得出的N^2个数正好是1到N^2之间的所有整数。

    对于正样的数列,如果我们将其中一个数列中所有数都加上一个常数,另外一个数列中所有数都减去一个常数,那么必然也得到一个符合条件的数列,所以我们可以认为这样得到的数列对和原先的数列对 是等价的,不在我们考虑范围之内。

    问题是,相互不等价的数列对有多少个?

    这个问题来源于CSDN中一道题目的讨论:

    http://community.csdn.net/Expert/TopicView.asp?id=4501259

    而最终的计算程序由于使用大整数,将用到GMP库。

    最终结果挺有意思,同N的因子分解结果有关系。比如

    N=p1^a1 *p2^a2*..*pt^at

    那么结果仅仅同a1,a2,...,at有关系,而同p1,p2,...,pt没有关系。

       
      对于整数N,对于一个序列  
      n0=N,   n1,   n2,...,nk  
      其中n(i+1)|n(i)而且n(i+1)>n(i),   nk=1  
      我们称这个序列为N一个长度为k的因子序列.  
      比如N长度为1的因子序列只有一个为N,1.  
      记N长度为s的因子序列的数目为L(N,s)  
      那么L(N,0)=0,L(N,1)=1  
      上面计数问题的结果即  
        f(N)=Sum{L(N,k)*[L(N,k)+L(N,k-1)],   for   k=1,2,3,...}  
      比如对于N=6=2*3  
      长度为1的因子序列1个   {6,1}  
                  2                     2个   {6,2,1},   {6,3,1}  
          长度大于3的因子序列没有  
      所以f(6)=1*(1+0)+2*(2+1)=7  
      而对于N=p^k,   长度为t的因子序列相当于从p,p^2,...,p^(k-1)中选择t-1个数,共有C(k-1,t-1)个  
      所以L(p^k,   t)=C(k-1,t-1)  
          f(p^k)=Sum{C(k-1,t-1)*[C(k-1,t-1)+C(k-1,t-2)],   t=1,2,...,k}  
                      =Sum{C(k-1,t-1)*C(k,t-1),   t=1,2,...,k}  
                      =Sum{C(k-1,s)*C(k,s),   s=0,1,...,k-1}  
                      =Sum{C(k-1,s)*C(k,k-s),   s=0,1,...,k-1}  
                      =C(2k-1,k)   (从2k-1个样品中取k个的方案正好是从前k-1个中取s个,后k个中取k-s个,对所有可能的s进行求和)  
                      =(2k-1)!/(k!*(k-1)!),即gxqcn的结论.  
       
      我现在写的程序就是对给定的N,先求出所有的L(N,s),然后计算出f(N).  
      还没有找到更加好的办法.  
       
      其实这个方法不仅仅对于N*N的方阵可用,对于将0,1,...,M*N-1填入一个M*N的矩阵的计数方案也可用.   
        
        
      其中L(N,s)也可以想象成下面的模型  
      假设  
      N=p1^r1*p2^r2*...*pt^rt  
      我们想象有一个袋子中总共装了r1+r2+...+rt个球,这些球总共有t种颜色,r1个为第一种颜色,r2个为第二种颜色,...,rt个为第t种颜色.  
      现在要分s次将袋子种的球取光,请问有多少种方案?  
      这个方案数就是L(N,s).  
     

    找到一种时间复杂度为O(L^2)次乘法的算法.  
      其中L=r1+r2+...+rt  
       
      定义C(m,n)=m!/(n!*(m-n)!)是组合数.  
       
      i)计算组合数C(m,n),其中m=1,2,...,L+max(r)-1.   0<=n<=m   (max(r)=max(r1,r2,...,rt))  
          计算方法  
              C(1,0)=C(1,1)=1  
          for(m=2;m<L+max(r);m++){  
                    C(m,0)=1;  
                    for(n=1;n<=m;n++)C(m,n)=C(m-1,n-1)+C(m-1,n);  
          }  
          总共花费O(L^2)次加法.  
       
      然后我们定义S(N,1)=1,S(0,k)=1   S(N,k)=S(N,k-1)+S(N-1,k),  
            其中S(N,k)就是k个非负整数和为N的表示方法数目(k个整数有序,也就是0+1和1+0不同)  
      ii)计算S(n,m),其中n=0,1,2,...,L;   1<=m<=L-n+1  
              使用上面递推式计算,时间复杂度也是O(L^2)次加法  
       
      最后一步直接计算L(N,k)  
          其中L(N,1)=1  
      iii)   L(N,k)=C(r1+k-1,k-1)*C(r2+k-1,k-1)*...*C(rt+k-1,k-1)  
                      -Sum{   S(j+1,k-j)*L(N,k-j-1),   for   j=0   to   k-1}  
        从L(N,1)开始递推计算到L(N,L),其中每步max(k,t)<=L次乘法,共L步,所以时间复杂度为O(L^2)次乘法.  
       
      有了L(N,k)后,我们就可以使用O(L)次乘法计算出f(N)了.

    发现S(n,m)其实就是C(n+m-1,m-1),所以只要事先计算好组合数就够了

     

      #include   <stdio.h>  
      #include   <stdlib.h>  
      #include   <memory.h>  
      #include   <gmp.h>  
       
      int   *factor_list;  
      int   factor_count;  
      int   L,   LAR;  
      mpz_t   *triangle;  
      mpz_t   *f;  
      mpz_t   N;  
       
      #define   TRIANGLE(x,y)     triangle[(x)*LAR+(y)]  
       
      void   set_triangle()  
      {  
      int   i,j;  
      triangle   =   (mpz_t   *)malloc(sizeof(mpz_t)*LAR*LAR);  
      for(i=0;i<LAR;i++)for(j=0;j<=i;j++)mpz_init(TRIANGLE(i,j));  
      mpz_set_ui(TRIANGLE(0,0),1);  
              mpz_set_ui(TRIANGLE(1,0),1);  
              mpz_set_ui(TRIANGLE(1,1),1);  
              for(i=2;i<LAR;i++){  
      mpz_set_ui(TRIANGLE(i,0),1);  
      mpz_set_ui(TRIANGLE(i,i),1);  
      for(j=1;j<i;j++){  
      mpz_add(TRIANGLE(i,j),TRIANGLE(i-1,j-1),TRIANGLE(i-1,j));  
      }  
              }  
      }  
       
       
      void   calc_f(){  
      int   i,k;  
      mpz_t   M,R;  
      mpz_init(M);  
      mpz_init(R);  
      f=   (mpz_t   *)malloc(sizeof(mpz_t)*(L+1));  
      for(i=0;i<=L;i++)mpz_init(f[i]);  
      mpz_set_ui(f[1],1);  
      printf("L[1]=1/n");  
      for(k=2;k<=L;k++){  
      mpz_set_ui(M,1);  
      for(i=0;i<factor_count;i++){  
      mpz_mul(M,M,TRIANGLE(factor_list[i]+k-1,k-1));  
      }  
      for(i=0;i<k-1;i++){  
      mpz_set(R,TRIANGLE(k,i+1));  
      mpz_mul(R,R,f[k-i-1]);  
      mpz_sub(M,M,R);  
      }  
      mpz_set(f[k],M);  
      printf("L[%d]=",k);  
      mpz_out_str(stdout,10,f[k]);  
      printf("/n");  
      }  
      mpz_clear(R);  
      mpz_clear(M);  
      }  
       
      void   output_result()  
      {  
      mpz_t   M,R;  
      int   i;  
      mpz_init(M);  
      mpz_init(R);  
      mpz_set_ui(M,1);  
      for(i=2;i<=L;i++){  
      mpz_set(R,f[i]);  
      mpz_add(R,R,f[i-1]);  
      mpz_mul(R,R,f[i]);  
      mpz_add(M,M,R);  
      }  
      printf("The   result   is:/n");  
      mpz_out_str(stdout,10,M);  
      printf("/n");  
      mpz_clear(R);  
      mpz_clear(M);  
      }  
       
      #define   PRIME_LIMIT   1048576  
      #define   SQR_LIMIT       1024  
      int   prime_flag[PRIME_LIMIT];  
      int   *prime_list;  
      int   prime_count;  
      void   init_prime(){  
      int   i,count;  
      memset(prime_flag,-1,sizeof(prime_flag));  
      prime_flag[0]=prime_flag[1]=0;  
      for(i=2;i<=SQR_LIMIT;i++){  
      if(prime_flag[i]){  
      int   j;  
      for(j=i*i;j<PRIME_LIMIT;j+=i)  
      prime_flag[j]=0;  
      }  
      }  
      for(i=2,count=0;i<PRIME_LIMIT;i++){  
      if(prime_flag[i])count++;  
      }  
      prime_count=count;  
      prime_list=(int   *)malloc(sizeof(int)*count);  
      for(i=2,count=0;i<PRIME_LIMIT;i++){  
      if(prime_flag[i]){  
      prime_list[count++]=i;  
      }  
      }  
      }  
       
      void   defactor()  
      {  
      int   i,pc,maxr;  
      mpz_t   R,M;  
      mpz_init(R);  
      mpz_init(M);  
      mpz_set(M,N);  
      for(i=0,pc=0;i<prime_count;i++){  
      if(!mpz_mod_ui(R,M,prime_list[i])){  
      pc++;  
      do{  
      mpz_fdiv_q_ui(M,M,prime_list[i]);  
      }while(!mpz_mod_ui(R,M,prime_list[i]));  
      if(!mpz_cmp_si(M,1))break;  
      }  
      }  
      if(mpz_cmp_si(M,1)){  
      int   r;  
      if(r=mpz_probab_prime_p(M,5)){//Using   prime   test   to   verify   the   left   is   a   prime  
      pc++;  
      if(r==1){  
      fprintf(stderr,"WARNING:The   left   factor   could   not   be   verified   to   be   prime   but   looks   like   to   a   prime.   It   is   treated   as   a   prime/n");  
      }  
      }else{  
      fprintf(stderr,"Cannot   find   all   prime   factors   of   input/n");  
      exit(-1);  
      }  
      }  
      factor_list=(int   *)malloc(sizeof(int)*pc);  
      factor_count=pc;L=0,maxr=0;  
      mpz_set(M,N);  
      for(i=0,pc=0;i<prime_count;i++){  
      if(!mpz_mod_ui(R,M,prime_list[i])){  
      factor_list[pc]=0;  
      do{  
      mpz_fdiv_q_ui(M,M,prime_list[i]);  
      factor_list[pc]++;  
      }while(!mpz_mod_ui(R,M,prime_list[i]));  
      L+=factor_list[pc];  
      if(maxr<factor_list[pc])maxr=factor_list[pc];  
      pc++;  
      if(!mpz_cmp_si(M,1))break;  
      }  
      }  
      if(mpz_cmp_si(M,1)){  
      factor_list[pc++]=1;  
      L++;  
      if(maxr<1)maxr=1;  
      }  
      LAR=L+maxr+1;  
      mpz_clear(R);  
      mpz_clear(M);  
      }  
       
       
      int  
      main(void)  
      {  
      mpz_init(N);  
              printf("Please   input   the   large   number:/n");  
              mpz_inp_str(N,stdin,10);  
      init_prime();  
      defactor();  
      set_triangle();  
      calc_f();  
      output_result();  
              mpz_clear(N);  
              return   0;  
      }   
       

    展开全文
  • [HAOI2009] 逆序对数列

    2018-10-23 09:48:00
    而且题目保证了是从1-n的自然数,所以不存在相同数字的情况。 我们设计状态\(dp[i][j]\)为长度为i的序列(也就是前\(i\)个自然数)排成的序列逆序数量为\(j\)的答案个数。 之后的转移就是往原先的序列塞下一个...
  • 波动数列

    2021-02-15 13:41:22
    这个数列中后一项总是比前一项增加2或者减少3,且每一项都为整数。 栋栋这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加 a 或者减少 b 整数数列可能有多少种呢? 输入格式 共一行,包含四...
  • 题目描述 给定一个长度为 n 数列,判断其是否为“牛”,是则输出“YES”,否则输出“NO”。 一个数列是“牛”,当且仅当其满足以下三个条件中至少一...= 数列中的每个数<=10^9 思路 我正在研究The One Probe模组
  • 数列中每个数vali满足1&lt;=vali&lt;=C。 初始时数列中每个数均为1,现在Rabbit要这个数列进行Q次操作,每次操作给出四个数:X Y A B,首先查询数列中值为X个数P,然后计算出L,R: L=(A+(P+B)2)mod N R...
  • dp[i][j]表示有i个数的排列方式逆序有j个的方案数。 因为dp这样转移为$dp[i][j]=\sum_{t=j-i+1}^{j}(dp[i-1]...这样i,j,t三层循环O(n^3)会T这时发现t的范围是在j-i+1到j之间,所以如果可以处理出每次循环j时的...
  • 数列分段 Section II

    2019-10-16 21:00:28
    题目链接:数列分段 Section II 题目描述:给定一个长度为N的数列,现在要将其分为M段(M<=N),分段要求连续的对数列进行分段,并且每段和的最大...首先先确定最大值的范围(大于等于数列中最大的数,小于等于数...
  • bzoj-1500 维修数列

    千次阅读 2015-06-28 08:36:37
    给出一个长度为n的数列和m个操作; 每个5,6操作输出一个答案; 被bz吃掉的数据范围: 你可以认为在任何时刻,数列中至少有1个数; 输入数据一定是正确的,即指定位置的数在数列中一定存在; 50%的数据中,任何...
  • 不等数列

    2016-06-19 20:07:00
    将1到n任意排列,然后在排列每两个数之间根据他们大小关系插入“>”和“<”。问在所有排列,有多少个排列恰好有k个“<”。答案2012取模。 【输入格式】 第一行2个整数n,k。 【输出格式】 ...
  • AcWing 1214. 波动数列

    2021-02-25 22:01:39
    这个数列中后一项总是比前一项增加2或者减少3,且每一项都为整数。 栋栋这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加 a 或者减少 b 整数数列可能有多少种呢? 输入格式 共一行,包含四...
  • Codevs 4357 不等数列

    2017-06-07 19:57:00
    不等数列 【题目描述】 将1到n任意排列,然后在排列每两个数之间根据他们大小关系插入“>”和“<”。问在所有排列,有多少个排列恰好有k个“<”。答案2012取模。 【输入格式】 第一行2个整数...
  • 模拟赛 不等数列

    2018-03-01 16:11:14
    将1到n任意排列,然后在排列每两个数之间根据他们大小关系插入“&gt;”和“&lt;”。问在所有排列,有多少个排列恰好有k个“&lt;”。答案2012取模。 【输入格式】 第一行2个整数n,k。 【输出...
  • 输入n个整数序列,要求这个数列进行去重操作; 所谓去重,是指这个序列每个重复出现整数,只保留该数第一次出现位置,删除其余位置 2.输入描述:输入包含两行,第一行包含一个正整数n(1 <= n <=...
  • 这个数列中后一项总是比前一项增加2或者减少3,且每一项都为整数。 栋栋这种数列很好奇,他想知道长度为 n和为 s 而且后一项总是比前一项增加 a 或者减少 b整数数列可能有多少种呢? 输入格式 共一行,包含四个...
  • 这个数列中后一项总是比前一项增加2或者减少3,且每一项都为整数。 栋栋这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加 a 或者减少 b 整数数列可能有多少种呢? 输入格式 共一行,包含四...
  • 数列互质 莫队+链表

    2019-07-20 16:24:34
    给出一个长度为n的序列,以及m组询问,求区间[li,ri]有多少数在该区间的出现次数与ki互质 数据范围 0<=n,m<=50000,0<=a[i]<=50000,0<=l,r,k<=50000 二、思考及解法 这道题很容易看出是莫...
  • 现在此研究中心欲使最后剩下数字为目标数,请你帮助他们完成这个任务(假设:在运算过程中的所有数都在longint范围内)。 若此数列为{12,10,4,3,5),目标数为4,E(n)表示n和第n+l...
  • 这个数列中后一项总是比前一项增加2或者减少3,且每一项都为整数。 栋栋这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加 a 或者减少 b 整数数列可能有多少种呢? 输入格式 共一行,包含四...
  • NOIP模拟赛 不等数列

    2019-09-30 23:40:54
    将1到n任意排列,然后在排列每两个数之间根据他们大小关系插入“>”和“<”。问在所有排列,有多少个排列恰好有k个“<”。答案2012取模。 【输入格式】 第一行2个整数n,k。 【输出格式】 ...
  • 7-78 特殊a串数列求和 (20分) 给定两个均不超过9的正整数a和n,要求编写程序求a+aa+aaa++⋯+aa⋯a(n个a)之和...如果设成int类型也,不过自己有些疑问,因为如果是9位就超出了int的范围。。 #include<iostream&g
  • 如果只是高中范围话,不好深入说明其中原理,只能证明这是对的递推式:a(n+1)=(A*an+B)/(C*an+D)(nN*,A,B,C,D为常数,C不为0,AD-BC不为0,a1与a2不等)其特征方程为x=(A*x+B)/(C*x+D)特征方程根称为该数列的不动...
  • 将1到n任意排列,然后在排列每两个数之间根据他们大小关系插入“>”和“<”。问在所有排列,有多少个排列恰好有k个“<”。答案2012取模。【输入格式】 第一行2个整数n,k。【输出格式】 一个整数表示答案。...
  • 如何能够快速求得斐波那契数列中某项值呢? 一个很显然方法是正向地叠加求解: <pre><code> javascript "use strict"; const N = 1000; let fibonacciNumber = []; for (let i &#...
  • 题目描述:将 1到 n任意排列,然后在排列每两个数之间根据他们大小关系插入“ >” 和“ <”。问在所有排列,有多少个排列恰好有 ...数据范围:对于 30%数据: n 对于 100%数据: k < n 简析: 显然这绝对不
  • 给定一个长度为n的整数数列,请你计算数列中的逆序的数量。 逆序的定义如下:对于数列的第 i 个和第 j 个元素,如果满足 i < j 且 a[i] > a[j],则其为一个逆序;否则不是。 输入格式 第一行包含整数n,...
  • 逆序对的数量

    2020-04-02 18:48:58
    给定一个长度为n的整数数列,请你计算数列中的逆序的数量。 逆序的定义如下:对于数列的第 i 个和第 j 个元素,如果满足 i < j 且 a[i] > a[j],则其为一个逆序;否则不是。 输入格式 第一行包含整数n,...

空空如也

空空如也

1 2 3 4 5 ... 13
收藏数 258
精华内容 103
关键字:

对数列中n的范围