标签:hid none pre 轻松 main ios div 范围 输入输出格式
给出两个正整数X和Y,求X和Y的最大公约数,奶牛可以轻松解决这个问题。
农夫Farmer John决定改一改题目去考验奶牛。农夫决定询问奶牛Q个问题,每个问题的格式是这样的:
农夫给定两个正整数a和b,农夫保证a≤b,然后农夫询问奶牛:在a至b的范围内,有没有哪个整数既是X的约数同时又是Y的约数?如果有,输出最大的那个;如果没有,输出-1。
第一行,两个正整数,X和Y。
第二行,一个整数数,Q。
接下来有Q行,每行两个正整数:a和b,其中保证a≤b。
共Q行,每行一个整数,每行对应农夫的一个问题。
200 120
3
9 40
25 35
10 15
40
-1
10
5
5
对于40%的数据:1≤X≤100,1≤Y≤100,1≤Q≤100,1≤a<b≤100;
对于100%的数据:1≤X≤1000000000,1≤Y≤1000000000,1≤Q≤30000,1≤a<b≤1000000000。
我们可以以根号n的时间复杂度来枚举出n的约数,然后暴力求公约数,再用二分来回应询问即可。
#include <iostream> #include <cstdio> #include <cmath> using namespace std; int x, y; int q; int ax[700000], cntx; int ay[700000], cnty; int a[1400000], cnt; void Init(int obj, int srobj, int a[], int & cnt) { for(register int i = 1; i <= srobj; ++i) { if(obj % i) continue; a[++cnt] = i; } for(register int i = cnt; i; --i) { a[++cnt] = obj / a[i]; } return; } void Work() { int i = 1, j = 1; while(i <= cntx && j <= cnty) { if(ax[i] == ay[j]) { a[++cnt] = ax[i]; ++i; ++j; } else if(ax[i] < ay[j]) ++i; else ++j; } return; } int Solve(int minn, int maxn) { int ans = -1; int lt = 1, rt = cnt, mid; while(lt <= rt) { mid = lt + rt >> 1; if(a[mid] <= maxn) ans = a[mid], lt = mid + 1; else rt = mid - 1; } if(ans >= minn) return ans; return -1; } int main() { scanf("%d%d%d", &x, &y, &q); Init(x, sqrt(x), ax, cntx); Init(y, sqrt(y), ay, cnty); Work(); ++q; int minn, maxn; while(--q) { scanf("%d%d", &minn, &maxn); printf("%d\n", Solve(minn, maxn)); } return 0; }
标签:hid none pre 轻松 main ios div 范围 输入输出格式
原文地址:https://www.cnblogs.com/kcn999/p/10356726.html