有一定难度的一道题目,网上已经有大神给出了思路,其实也就是按照别人的方法得知最大的k值不会超过26,那么对于不同的k值,我们直接二分查找是否存在对应的n值即可,如果存在就保存对应的结果,如果不存在就进行下一轮的查找,具体实现见如下代码:
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
#include<functional>
using namespace std;
typedef long long LL;
int judge(LL mid,LL aim,LL k){
LL r = 1;
for (LL i = 1; i <= k; i++){
if (aim*i / r / (mid - i + 1) == 0) return 1;//代表mid取大了
r = r*(mid - i + 1) / i;
}
if (r == aim) return 0;//正好
return -1;//mid取小了
}
int main(){
int Case;
cin >> Case;
vector<pair<LL, LL>> res;
while (Case--){
res.clear();
LL m;
cin >> m;
res.push_back(make_pair(m,1));
res.push_back(make_pair(m,m-1));
for (int i = 2; i <= 30; i++){
LL left = i, right = m;
while (left <= right){
LL mid = (left + right) / 2;
LL temp = judge(mid, m, i);
if (temp == 0){
res.push_back(make_pair(mid,i));
res.push_back(make_pair(mid, mid - i));
break;
}
else if (temp == 1){
right = mid - 1;
}
else left = mid + 1;
}
}
sort(res.begin(),res.end());
res.resize(unique(res.begin(),res.end())-res.begin());
cout << res.size() << endl;
int amount = res.size() - 1;
for (int i = 0; i < amount; i++){
cout << "(" << res[i].first << "," << res[i].second << ") ";
}
cout << "(" << res[amount].first << "," << res[amount].second << ")\n";
}
return 0;
}