亲密数对、递归求逆

/*
 * @Issue: 亲密数对问题:从键盘输入正整数 M 和 N(M<N),输出 M 和 N 之间所有的亲密数对。
           亲密数对的定义如下:两个正整数 x 和 y,若 x 的所有因子之和(不包括 x 本身)等于 y,
           并且 y 的所有因子之和(不包括 y 本身)等于 x,则 x 和 y 为亲密数对。
 * @Author: 一届书生
 * @LastEditTime: 2020-02-21 10:04:41
 */
#include<iostream>
using namespace std;
#define maxn 10000
int getSum(int n){
    int cnt=1;
    for(int i=2;i<=n/2;i++){
        if(n%i==0){
            cnt+=n/i;
        }
    }
    return cnt;
}

int main(){
    int qin[maxn];
    int m,n;
    while(cin>>m>>n){
        for(int i=m;i<=n;i++){
            qin[i]=getSum(i);
        }
        // for(int i=m;i<=n;i++){
        //     cout<<qin[i]<<" ";
        // }
        for(int j=m;j<=n;j++){
            if(j==qin[qin[j]]&&qin[j]!=1){          //别判断错了,是j和qin[qin[j]]判等
                cout<<qin[j]<<" "<<qin[qin[j]]<<endl;
                qin[qin[j]]=0;
            }
        }
    }
    return 0;
}

  

/*
 * @Issue: 从键盘输入一个整数 n,输出 n 的逆,如输入 12345,输出 54321,请尽量设计递归函数实现。
 * @Author: 一届书生
 * @LastEditTime: 2020-02-21 10:20:40
 */
#include<iostream>
using namespace std;

void reverse(int n){
    cout<<n%10;
    n/=10;
    if(n>0)reverse(n);
}

int main(){
    int n;
    while(cin>>n){
        reverse(n);
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/52dxer/p/12340892.html

时间: 2024-10-10 10:37:26

亲密数对、递归求逆的相关文章

数状数组求逆序对

逆序对在很多地方用的到.以前都是用归并排序或线段树求,在<mato的文件管理>看到有人用树状数组求,很简单!整理如下: 思路: 首先,开一个大小为这些数的最大值的数组,作为树状数组. 然后,将各个数按顺序依次加入该数组.方法为:这个数大小对应的它在线段树中的位置,对这个位置上的数加1,并更新树状数组.所以当前树状数组中存着所有原数字序列中当前数前面的数,而getsum(i)就是 i 前面小于等于 i 的数的个数.i-getsum(i)-1也就是大于它的个数.这就是逆序对了. 把每一个的逆序对数

分治法题目整理分析 找第k小的数/求逆序对数目/派

设计一个平均时间为O(n)的算法,在n(1<=n<=1000)个无序的整数中找出第k小的数. 提示:函数int partition(int a[],int left,int right)的功能是根据a[left]~a[right]中的某个元素x(如a[left])对a[left]~a[right]进行划分,划分后的x所在位置的左段全小于等于x,右段全大于等于x,同时利用x所在的位置还可以计算出x是这批数据按升非降序排列的第几个数.因此可以编制int find(int a[],int left,

分治法 求 逆序对数 的个数 时间复杂度为O(n*logn)

思路: 分治法 归并排序的过程中,有一步是从左右两个数组中,每次都取出小的那个元素放到tmp[]数组中 右边的数组其实就是原数组中位于右侧的元素.当不取左侧的元素而取右侧的元素时,说明左侧剩下的元素均比右侧的第一个元素大,即均能构成一个逆序对.假设现在左侧剩余n个元素,则逆序对数+n. 另外,如果当所有右侧的元素都取完,但是左侧仍然有元素剩余时,左侧剩余的元素已经在之前的运算中加到了逆序对中,不需要再添加一次 下面给出 归并排序 和 求逆序对数 两份代码: code1: 归并排序 #includ

ZOJ3574(归并排序求逆数对)

Under Attack II Time Limit: 5 Seconds      Memory Limit: 65536 KB Because of the sucessfully calculation in Under Attack I, Doctor is awarded with Courage Cross and promoted to lieutenant. But the war seems to end in never, now Doctor has a new order

hdu 4911 求逆序对数+树状数组

http://acm.hdu.edu.cn/showproblem.php?pid=4911 给定一个序列,有k次机会交换相邻两个位置的数,问说最后序列的逆序对数最少为多少. 实际上每交换一次能且只能减少一个逆序对,所以问题转换成如何求逆序对数. 归并排序或者树状数组都可搞 树状数组: 先按大小排序后分别标号,然后就变成了求1~n的序列的逆序数,每个分别查询出比他小的用i减,在把他的值插入即可 #include <cstdio> #include <cstdlib> #includ

线段数 --- (单点更新、求逆序对)

Minimum Inversion Number Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy i < j and ai > aj. For

C语言用递归求斐波那契数,让你发现递归的缺陷和效率瓶颈

递归是一种强有力的技巧,但和其他技巧一样,它也可能被误用. 一般需要递归解决的问题有两个特点: 存在限制条件,当符合这个条件时递归便不再继续: 每次递归调用之后越来越接近这个限制条件. 递归使用最常见的一个例子就是求阶乘,具体描述和代码请看这里:C语言递归和迭代法求阶乘 但是,递归函数调用将涉及一些运行时开销--参数必须压到堆栈中,为局部变量分配内存空间(所有递归均如此,并非特指求阶乘这个例子),寄存器的值必须保存等.当递归函数的每次调用返回时,上述这些操作必须还原,恢复成原来的样子.所以, 基

【BZOJ】4555: [Tjoi2016&amp;Heoi2016]求和 排列组合+多项式求逆 或 斯特林数+NTT

[题意]给定n,求Σi=0~nΣj=1~i s(i,j)*2^j*j!,n<=10^5. [算法]生成函数+排列组合+多项式求逆 [题解]参考: [BZOJ4555][Tjoi2016&Heoi2016]求和-NTT-多项式求逆 $ans=\sum_{i=0}^{n}\sum_{j=0}^{i}s(i,j)*2^j*j!$ 令$g(n)=\sum_{j=0}^{n}s(n,j)*2^j*j!$ 则ans是Σg(i),只要计算出g(i)的生成函数就可以统计答案. g(n)可以理解为将n个数划分

(c) hdu1394* (求逆序对数)(线段树)

(c) hdu1394 如在阅读本文时遇到不懂的部分,请在评论区询问,或跳转 线段树总介绍 线段树求逆序对数比较少见啊(归并排序多快啊...但是本文是讲解线段树写法...),何况这题还加了点别的玩意儿... 1. 本来这种题目要离散化的,可是体中保证了数列0~n-1. 2. 每次把首位放到最末,显然不能 每次都求逆序对 ,于是又到了推 倒 导时间. 由 a1 a2 ... an 变为 a2 a3 ... an a1 减少的逆序对数为 a2~an中比a1小的数的个数 增加的逆序对数为 a2~a1中