xtuoj A+B Again(在某个数中找大于m的最小约数)

新生赛:

Accepted : 15   Submit : 243
Time Limit : 1000 MS   Memory Limit : 65536 KB 

题目描述

上次趣味赛小明的a+b坑了不少不喜欢思考的同学,小明为了表示歉意, 这次出了道简单的a+b给大家当签到题,希望大家能开心刷题。 那么,题目来了!!!

求使得b/(a+x)为整数的最小正整数x的值。

输入

第一行是一个整数K(K≤10000),表示样例的个数。 以后每行一个样例,为两个正整数a,b(1≤a,b≤108)。

输出

每行输出一个样例的结果,如果不存在这样的x,输出-1。

样例输入

3
1 2
1 3
1 4

样例输出

1
2
1

思路:开始我找出b的所有质因数 复杂度logN的,后来求每个质因数生成的约数即质因数m*(1,2,3...)(复杂度大了)和筛法的思想类似,再sort,再扫一遍找大于a的最小约数,结果T了,在10^7的数据大小时就T了。

所以改一下,不需要生成所有的约数,每个质因数只要生成一个大于a的最小约数就可,这样就一共生成了和质因数数目一样多的约数(小于OlogN),再sort即可。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<algorithm>
#include<set>
#include<vector>
using namespace std;
int a,b,su;
vector<int>s;
vector<int>all;
void solve()
{
    int temp=b;
    if(a>=temp){ cout<<"-1"<<endl; return; } //特判
    //找质因数:
        for(int i=2;i*i<=temp;i++)
        {
            if(temp%i==0)
            {
                s.push_back(i);
                while(temp%i==0) temp/=i;
            }
        }
   s.push_back(b);         // 因为b本身可能就是素数,所以要在vector里加b,就算不是素数,也对结果无影响。
   for(int i=0;i<s.size();i++) //生成s.size()个约数。
    {
        su=s[i];
        int m=a/su+1;
        all.push_back(su*m);
    }

    sort(all.begin(),all.end());
    for(int i=0;i<all.size();i++)
    if(all[i]>a) {cout<<all[i]-a<<endl;return ;}

}
int main()
{
    int _;
    cin>>_;
    while(_--)
    {
        cin>>a>>b;
        s.clear();
        all.clear();
        solve();
    }
    return 0;
}
时间: 2024-11-06 07:49:43

xtuoj A+B Again(在某个数中找大于m的最小约数)的相关文章

A+B Again(在某个数中找大于m的最小约数)

A+B Again Accepted : 15   Submit : 243 Time Limit : 1000 MS   Memory Limit : 65536 KB  题目描述 上次趣味赛小明的a+b坑了不少不喜欢思考的同学,小明为了表示歉意, 这次出了道简单的a+b给大家当签到题,希望大家能开心刷题. 那么,题目来了!!! 求使得b/(a+x)为整数的最小正整数x的值. 输入 第一行是一个整数K(K≤10000),表示样例的个数. 以后每行一个样例,为两个正整数a,b(1≤a,b≤108

【海量数据处理】N个数中找出最大的前K个数

N个数中找出最大的前K个数,需要用小堆实现. 分析:由于小堆的堆顶存放堆中最小的数据,可以通过与堆顶数据进行比较,将大数据存放在堆中,注意在每次改变堆顶数据后,进行调堆,使堆顶一直存放整个堆中最小元素. void AdjustDown(int *a, size_t root, size_t size)//下调 {//小堆 size_t parent = root; size_t child = parent * 2 + 1; while (child < size) { if (child + 

ytu 1061: 从三个数中找出最大的数(水题,模板函数练习 + 宏定义练习)

1061: 从三个数中找出最大的数Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 154  Solved: 124[Submit][Status][Web Board] Description 定义一个带参的宏(或者模板函数),从三个数中找出最大的数. Input 3个短整型数,空格隔开 3个实数,空格隔开 3个长整数,空格隔开 Output 最大的数,对于实数保留2位小数. Sample Input 1 2 3 1.5 4.7 3.2 123456

三个数中找最大

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace 三个数中找最大 { class Program { static void Main(string[] args) { Console.WriteLine("三个数中找最大"); int A = int.Parse(Console.ReadLine()); //Console.ReadLine()

面试题-10亿个数中找出最大的10000个数(top K问题)

一个较好的方法:先拿出10000个建立小根堆,对于剩下的元素,如果大于堆顶元素的值,删除堆顶元素,再进行插入操作,否则直接跳过,这样知道所有元素遍历完,堆中的10000个就是最大的10000个.时间复杂度: m + (n-1)logm = O(nlogm) 优化的方法:可以把所有10亿个数据分组存放,比如分别放在1000个文件中(如果是字符串hash(x)%M).对每个文件,建立大小为10000的小根堆,然后按有序数组的合并合并起来,取出最大的10000个即是答案. top K问题 在大规模数据

脑洞题目 - 改自从一组无序数组中找不存在的最小正整数

无聊想的题目,但题目创意改自从一组无序数组中找不存在的最小正整数.并不难,但也有陷阱,比考虑0和负数... /** * 从无序数组中找不存在的最小正整数 * 我的要求:比如:{3,4,6,9,20}中 最小的不存在的正整数为2 */ #include <stdio.h> int main() { int arr[] = {-5, -10, 42, 29, 18, -3, 8, 20, -1}; int i, j, temp; for(i = 1; i < sizeof(arr)/size

100万个数中找出最大的前K个数

拿到这个题目我想到了很多方法,但是在我想到的方法中,要把在100万个数中找到前k个数,都不适用.最后通过我的不断研究,我想到了我认为最简单的方法,就是利用堆来做这道题目. 下面我分析一下我用堆排序的思路: 1.我先建一个大小为k的堆. 2.把100万中前k个数放到这个堆中. 3.把这个堆调成小堆. 4.把100万个从k到100万之间的数字拿出来和堆的根结点作比较. 5.如果根结点小于这之间的某一个数,就把这个数拿给根结点,然后继续调成小堆.否则继续找 6.直到找完这100万个数,堆中放的就是最大

在四个数中找最大值和最大值

// // Copyright (C) 2014软件1班 // All rights reseved. // 作 者:A36 黄阿德 // 完成日期:2014年12月4日 // // 问题描述:创建一个程序找四个数的最小值和最大值,然后输出 // 输入描述:输入四个实数 // 输出描述:两个数,最小值和最大值 // using System; using System.Collections.Generic; using System.Linq; using System.Text; using

hdu 1258 从n个数中找和为t的组合

题意:首先给你一个t,然后是n,后面输入n个数,然后让你求的是n个数中和为t的序列总共有多少种,把他们按从左到右的顺序输出来. Sample Input4 6 4 3 2 2 1 15 3 2 1 1400 12 50 50 50 50 50 50 25 25 25 25 25 250 0 Sample OutputSums of 4:43+12+22+1+1Sums of 5:NONESums of 400:50+50+50+50+50+50+25+25+25+2550+50+50+50+50