#include <iostream> #include <cmath> #include <vector> using namespace std; struct node{ int left; int right; }; int main() { long N, M; long long sum = 0; vector<node> nodes; while (cin >> N >> M) { if (N == 0 && M == 0) break; for (long n = N; n >=1; n--) { if ((2*M-n*n+n)%(2*n)!=0) continue; long long a1 = (2 * M - n*n + n) / (2 * n); long long an = a1 + n - 1; if (a1 >= 1 && a1 <= N && an >= 1 && an <= N && a1 <= an) { //node node; //node.left = a1; //node.right = an; //nodes.push_back(node); cout << "[" << a1 << "," << an << "]" << endl; } } //for (node node : nodes) //{ // cout << "[" << node.left << "," << node.right << "]" << endl; //} cout << endl; } return 0; }
超时
a1 = k
an = k + n - 1
M = n*(2k+n-1)/2
解的
k = M/n - (n-1)/2,这个不能这样写,要写在一起
(2M-n*n-n)/(2*n)。否则对于30/4 - 3/2,会忽略这样的结果,如果先通分当然也就可以。
超时
利用a1>=1这个条件可以减少循环次数
2M - n*n >n
2M > n*n - n>n*n
sqrt(2M)>n
#include <iostream> #include <cmath> #include <vector> using namespace std; struct node{ int left; int right; }; int main() { long N, M; long long sum = 0; vector<node> nodes; while (cin >> N >> M) { if (N == 0 && M == 0) break; for (long n = sqrt(2*M); n >=1; n--) { if ((2*M-n*n+n)%(2*n)!=0) continue; long a1 = (2 * M - n*n + n) / (2 * n); long an = a1 + n - 1; if (a1 >= 1 && a1 <= N && an >= 1 && an <= N && a1 <= an) { //node node; //node.left = a1; //node.right = an; //nodes.push_back(node); cout << "[" << a1 << "," << an << "]" << endl; } } //for (node node : nodes) //{ // cout << "[" << node.left << "," << node.right << "]" << endl; //} cout << endl; } return 0; }