题目大意
给定 n n n,求出集合 S = { ⌊ x i ⌋ ∣ i ∈ [ 1 , n ] } S = \{\lfloor \frac{x}{i}\rfloor | i \in[1,n]\} S={⌊ix⌋∣i∈[1,n]},然后对集合 S S S去重并降序排序得到新集合 S ′ S' S′。给定 x x x,求 ⌊ x i ⌋ \lfloor \frac{x}{i}\rfloor ⌊ix⌋在集合 S ′ S' S′中是第几大。
解题思路
首先1-100打表每个数对应的集合,然后就是找规律了,这个题如何找呢,首先不难发现 x x x比较小时,那么 x x x是几答案就是几,测试几个数后不难发现这个界限在 n \sqrt{n} n附近,先假设为 n \sqrt{n} n,当 x x x大于界限时,有时候会有 n \sqrt{n} n个数,有时候会有 n − 1 \sqrt{n} - 1 n−1个数,然后我们可以发现当一个数恰为平方数时,其后面的 n − 1 \sqrt{n}-1 n−1个数和它一样,答案为 2 ∗ n − ⌊ n x ⌋ 2*\sqrt{n} - \lfloor \frac{n}{x} \rfloor 2∗n−⌊xn⌋,否则答案为 2 ∗ n − ⌊ n x ⌋ + 1 2*\sqrt{n} - \lfloor \frac{n}{x} \rfloor + 1 2∗n−⌊xn⌋+1
//
// Created by Happig on 2021/2/21.
//
#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
#define ENDL "\n"
#define lowbit(x) (x & (-x))
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
const double eps = 1e-8;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double dinf = 1e300;
const ll INF = 1e18;
const int Mod = 1e9 + 7;
const int maxn = 2e5 + 10;
set<int> s[105];
void table() {
for (int i = 1; i <= 100; i++) {
for (int j = 1; j <= i; j++) {
s[i].insert(i / j);
}
cout << i << ": ";
for (auto j = s[i].rbegin(); j != s[i].rend(); j++) cout << *j << " ";
cout << endl;
}
}
int getAns(int n, int x) {
int cnt = 1, cur = n / x;
for (auto j = s[n].rbegin(); j != s[n].rend(); j++, cnt++) {
if (*j == cur) {
return cnt;
}
}
return 0;
}
int solve(int n, int x) {
int m = sqrt(n);
int temp;
if (m * m == n || n - m * m < m) {
temp = m;
} else temp = m + 1;
if (x <= temp) {
return x;
} else {
return temp + m - n / x;
}
}
void duipai() {
for (int i = 1; i <= 100; i++) {
for (int j = 1; j <= i; j++) {
if (getAns(i, j) != solve(i, j)) {
cout << i << " " << j << endl;
}
}
}
}
int main() {
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
// table();
// duipai();
// cout << "finish duipai" << endl;
int t, n, x;
cin >> t;
while (t--) {
cin >> n >> x;
int m = sqrt(n);
int temp;
if (m * m == n || n - m * m < m) {
temp = m;
} else temp = m + 1;
if (x <= temp) {
cout << x << ENDL;
} else {
cout << temp + m - n / x << ENDL;
}
}
return 0;
}