poj2100(尺取模型,总结)

来源:互联网 发布:知乎 美国epic公司 编辑:程序博客网 时间:2024/05/29 21:34
/*translation:给出一个数,求一系列连续的数字使得它们的平方和等于这个数solution:尺取法即可note:#: 这道题有以下几个坑。一是L和R要从1开始,二是判断循环结束时我用了while(R*R<=n&&L*L<=n)正确姿势是只判断L,因为R有可能在最后一次循环中超出n。*: 尺取法的总结:尺取法本质上是将一个区间不断向前推进,以期获得解的过程。在此期间,尾部不断去掉不再需要的元素,头部不断向前推进获得新的元素。同时维护必要的值,如区间的和等。。。但是使用尺取法的一个重要条件就是在推进过程中值的变化一定是单调的。尺取法易错的点:这个要结合题意来看,但是一般会有如下几个易错的点:1,判断循环的结束上出错,如本题。2,当L,R相等时如何处理(本题其实不必考虑这个,而且去掉这个步骤速度还会更快)3,L和R的初始化,如本题。初始化的位置一定要在合法范围,以免出错!date:2016.11.14*/#include <iostream>#include <cstdio>#include <cmath>#include <utility>#include <vector>using namespace std;const int maxn = 1e7 + 5;typedef long long ll;typedef pair<ll, ll> P;ll n;vector<P> ans;int main(){//freopen("in.txt", "r", stdin);    while(cin >> n){ans.clear();ll L = 1, R = 1, sum = 0;while(L * L <= n){if(sum < n)sum += R * R, R++;else if(sum > n)sum -= L * L, L++;else{ans.push_back(make_pair(L, R));sum += R * R;R++;}if(L == R)sum += R * R, R++;}cout << ans.size() << endl;for(ll i = 0; i < ans.size(); i++){cout << ans[i].second - ans[i].first << " ";for(ll j = ans[i].first; j < ans[i].second; j++)cout << j << (j + 1 == ans[i].second ? '\n' : ' ');}    }    return 0;}

0 0