【003】平方求和

来源:互联网 发布:2016欧洲杯c罗数据 编辑:程序博客网 时间:2024/05/19 12:17

  • 平方求和
    • 题目描述
    • 输入输出
    • 示例输入
    • 实例输出
    • DFS Depth First Search
    • cache优化
    • 剪枝
    • 深度剪枝
    • 预测剪枝
    • BFS Breath First Search

平方求和

题目描述

对于一个非负整数n,最少需要几个完全平方数,使其和为n?

输入输出

输入
- 第一行是n;如果n为-1,表示输入结束
输出
- 针对每组数据,输出最少需要的完全平方数

示例输入

3
4
5
-1

实例输出

3
1
2

#include <iostream>#include <cstdio>#include <fstream>#include <ctime>using namespace std;class SqureSum {public:    int search(int n) {        if (n == 0) return n;        int result = n;        for (int i=1; i*i<=n; ++i) {            int temp = search(n - i*i);            if (temp + 1 < result) result = temp + 1;        }        return result;    }};int main() {    SqureSum ss;    ifstream is("../input.txt");    int n;    is >> n;    while (n != -1) {        clock_t start = clock();        printf("%d Result %d ", n, ss.search(n));        clock_t end = clock();        printf("Time: %fms\n", (float)(end - start)/CLOCKS_PER_SEC*1000);        is >> n;    }    return 0;}

输出

3 Result 3 Time: 0.000000ms
4 Result 1 Time: 0.000000ms
5 Result 2 Time: 0.000000ms
6 Result 3 Time: 0.000000ms
7 Result 4 Time: 0.000000ms
8 Result 2 Time: 0.000000ms
9 Result 1 Time: 0.000000ms
10 Result 2 Time: 0.000000ms
21 Result 3 Time: 0.000000ms
31 Result 4 Time: 1.000000ms
41 Result 2 Time: 19.000000ms
51 Result 3 Time: 573.000000ms
61 Result 2 Time: 17303.000000ms

cache优化

#include <iostream>#include <cstdio>#include <fstream>#include <ctime>#include <map>using namespace std;class SqureSum {private:    map<int, int> cache;public:    int search(int n) {        if (n == 0) return n;        if (cache.find(n) != cache.end()) return cache[n];        int result = n;        for (int i=1; i*i<=n; ++i) {            int temp = search(n - i*i);            if (temp + 1 < result) result = temp + 1;        }        cache[n] = result;        return result;    }};int main() {    SqureSum ss;    ifstream is("../input.txt");    int n;    is >> n;    while (n != -1) {        clock_t start = clock();        printf("%d Result %d ", n, ss.search(n));        clock_t end = clock();        printf("Time: %fms\n", (float)(end - start)/CLOCKS_PER_SEC*1000);        is >> n;    }    return 0;}

输出

3 Result 3 Time: 0.000000ms
4 Result 1 Time: 0.000000ms
5 Result 2 Time: 0.000000ms
6 Result 3 Time: 0.000000ms
7 Result 4 Time: 0.000000ms
8 Result 2 Time: 0.000000ms
9 Result 1 Time: 0.000000ms
10 Result 2 Time: 0.000000ms
21 Result 3 Time: 0.000000ms
31 Result 4 Time: 0.000000ms
41 Result 2 Time: 0.000000ms
51 Result 3 Time: 0.000000ms
61 Result 2 Time: 0.000000ms
101 Result 2 Time: 0.000000ms
1001 Result 3 Time: 14.000000ms
10001 Result 2 Time: 560.000000ms

剪枝

#include <iostream>#include <cstdio>#include <fstream>#include <ctime>#include <map>#include <cmath>using namespace std;class SqureSum {private:    map<int, int> cache;public:    int search(int n) {        if (n == 0) return n;        if (cache.find(n) != cache.end()) return cache[n];        int result = n;        int ceil = (int)(sqrt(n));        if (ceil * ceil == n) {            cache[n] = 1;            return 1;        }        for (int i=ceil; i>0; --i) {            int temp = search(n - i*i);            if (temp + 1 < result) result = temp + 1;        }        cache[n] = result;        return result;    }};int main() {    SqureSum ss;    ifstream is("../input.txt");    int n;    is >> n;    while (n != -1) {        clock_t start = clock();        printf("%d Result %d ", n, ss.search(n));        clock_t end = clock();        printf("Time: %fms\n", (float)(end - start)/CLOCKS_PER_SEC*1000);        is >> n;    }    return 0;}

输出

3 Result 3 Time: 0.000000ms
4 Result 1 Time: 0.000000ms
5 Result 2 Time: 0.000000ms
6 Result 3 Time: 0.000000ms
7 Result 4 Time: 0.000000ms
8 Result 2 Time: 0.000000ms
9 Result 1 Time: 0.000000ms
10 Result 2 Time: 0.000000ms
21 Result 3 Time: 0.000000ms
31 Result 4 Time: 0.000000ms
41 Result 2 Time: 0.000000ms
51 Result 3 Time: 0.000000ms
61 Result 2 Time: 0.000000ms
101 Result 2 Time: 0.000000ms
1001 Result 3 Time: 15.000000ms
10001 Result 2 Time: 540.000000ms
100001 Result 3 Time: 21555.000000ms

深度剪枝

#include <iostream>#include <cstdio>#include <fstream>#include <ctime>#include <map>#include <cmath>using namespace std;class SqureSum {private:    map<int, int> cache;    int best = 999;public:    int search(int n, int depth) {        if (n == 0) return n;        if (cache.find(n) != cache.end()) return cache[n];        if (depth > best) return n;        int result = n;        int ceil = (int)(sqrt(n));        if (ceil * ceil == n) {            cache[n] = 1;            if (best > depth) best = depth;            return 1;        }        for (int i=ceil; i>0; --i) {            int temp = search(n - i*i, depth + 1);            if (temp + 1 < result) result = temp + 1;            if (best > temp+depth) best = temp + depth;            if (temp == 1) break;        }        cache[n] = result;        return result;    }};int main() {    SqureSum ss;    ifstream is("../input.txt");    int n;    is >> n;    while (n != -1) {        clock_t start = clock();        printf("%d Result %d ", n, ss.search(n, 0));        clock_t end = clock();        printf("Time: %fms\n", (float)(end - start)/CLOCKS_PER_SEC*1000);        is >> n;    }    return 0;}

输出

3 Result 3 Time: 0.000000ms
4 Result 1 Time: 0.000000ms
5 Result 2 Time: 0.000000ms
6 Result 3 Time: 0.000000ms
7 Result 4 Time: 0.000000ms
8 Result 2 Time: 0.000000ms
9 Result 1 Time: 0.000000ms
10 Result 2 Time: 0.000000ms
21 Result 3 Time: 0.000000ms
31 Result 4 Time: 0.000000ms
41 Result 3 Time: 0.000000ms
51 Result 3 Time: 0.000000ms
61 Result 13 Time: 0.000000ms
101 Result 2 Time: 0.000000ms
1001 Result 3 Time: 0.000000ms
10001 Result 2 Time: 0.000000ms
100001 Result 3 Time: 1.000000ms
1000001 Result 2 Time: 0.000000ms
10000001 Result 3 Time: 0.000000ms
100000001 Result 2 Time: 0.000000ms

预测剪枝

#include <iostream>#include <cstdio>#include <fstream>#include <ctime>#include <map>#include <cmath>using namespace std;class SqureSum {private:    map<int, int> cache;    int best = 999;public:    int search(int n, int depth) {        if (n == 0) return n;        if (cache.find(n) != cache.end()) return cache[n];        if (depth > best) return n;        int result = n;        int ceil = (int)(sqrt(n));        if (ceil * ceil == n) {            cache[n] = 1;            if (best > depth) best = depth;            return 1;        }        if (depth + 1 < best) {            for (int i = ceil; i > 0; --i) {                int temp = search(n - i * i, depth + 1);                if (temp + 1 < result) result = temp + 1;                if (best > temp + depth) best = temp + depth;                if (temp == 1) break;            }        }        cache[n] = result;        return result;    }};int main() {    SqureSum ss;    ifstream is("../input.txt");    int n;    is >> n;    while (n != -1) {        clock_t start = clock();        printf("%d Result %d ", n, ss.search(n, 0));        clock_t end = clock();        printf("Time: %fms\n", (float)(end - start)/CLOCKS_PER_SEC*1000);        is >> n;    }    return 0;}

输出

3 Result 3 Time: 1.000000ms
4 Result 1 Time: 0.000000ms
5 Result 5 Time: 0.000000ms
6 Result 6 Time: 0.000000ms
7 Result 7 Time: 0.000000ms
8 Result 8 Time: 0.000000ms
9 Result 1 Time: 0.000000ms
10 Result 10 Time: 0.000000ms
21 Result 21 Time: 0.000000ms
31 Result 31 Time: 0.000000ms
41 Result 41 Time: 0.000000ms
51 Result 51 Time: 0.000000ms
61 Result 61 Time: 0.000000ms
101 Result 101 Time: 0.000000ms
1001 Result 1001 Time: 0.000000ms
10001 Result 10001 Time: 0.000000ms
100001 Result 100001 Time: 0.000000ms
1000001 Result 1000001 Time: 0.000000ms
10000001 Result 10000001 Time: 0.000000ms
100000001 Result 100000001 Time: 0.000000ms

#include <iostream>#include <cstdio>#include <fstream>#include <ctime>#include <map>#include <cmath>#include <queue>using namespace std;class SqureSum {private:    map<int, int> cache;    int best = 999;public:    int search(int n, int depth) {        if (n == 0) return n;        if (cache.find(n) != cache.end()) return cache[n];        if (depth > best) return n;        int result = n;        int ceil = (int)(sqrt(n));        if (ceil * ceil == n) {            cache[n] = 1;            if (best > depth) best = depth;            return 1;        }        if (depth + 1 < best) {            for (int i = ceil; i > 0; --i) {                int temp = search(n - i * i, depth + 1);                if (temp + 1 < result) result = temp + 1;                if (best > temp + depth) best = temp + depth;                if (temp == 1) break;            }        }        cache[n] = result;        return result;    }    int bfs(int n) {        queue<int> q;        q.push(n);        q.push(-1);        int need = 1;        while (!q.empty()) {            int tmp = q.front();            q.pop();            if (tmp < 0) {                q.push(tmp-1);                ++need;            } else {                int ceil = (int)sqrt(tmp);                if (ceil * ceil == tmp) break;                for (int i=ceil; i>0; --i) {                    q.push(tmp - i*i);                }            }        }        return need;    }};int main() {    SqureSum ss;    ifstream is("../input.txt");    int n;    is >> n;    while (n != -1) {        clock_t start = clock();        // printf("%d Result %d ", n, ss.search(n, 0));        printf("%d Result %d ", n, ss.bfs(n));        clock_t end = clock();        printf("Time: %fms\n", (float)(end - start)/CLOCKS_PER_SEC*1000);        is >> n;    }    return 0;}

输出

3 Result 3 Time: 0.000000ms
4 Result 1 Time: 0.000000ms
5 Result 2 Time: 0.000000ms
6 Result 3 Time: 0.000000ms
7 Result 4 Time: 0.000000ms
8 Result 2 Time: 0.000000ms
9 Result 1 Time: 0.000000ms
10 Result 2 Time: 0.000000ms
21 Result 3 Time: 0.000000ms
31 Result 4 Time: 0.000000ms
41 Result 2 Time: 0.000000ms
51 Result 3 Time: 0.000000ms
61 Result 2 Time: 0.000000ms
101 Result 2 Time: 0.000000ms
1001 Result 3 Time: 0.000000ms
10001 Result 2 Time: 0.000000ms
100001 Result 3 Time: 4.000000ms
1000001 Result 2 Time: 0.000000ms
10000001 Result 3 Time: 256.000000ms
100000001 Result 2 Time: 0.000000ms

原创粉丝点击