Algorithm design and analysis of experiments report

Experimental design and operation algorithm represents a set of
https://www.cnblogs.com/31415926535x/p/10963938.html

Purpose

Through this experience to understand the experiment and master the basic idea of ​​recursive divide and conquer algorithm and greedy algorithm and ability to solve specific problems, to achieve problem-solving process by c ++, further familiar with the process algorithm.

Content Experiments

Experimental roughly divided into three parts: Overview , recursive and divide and conquer strategy , greedy algorithm . For each type of issue, at least one subject about and use the code to verify the correctness of the algorithm, analyze the feasibility of the algorithm.

Outline

Statistics problems

topic

问题描述:

  一本书的页码从自然数1 开始顺序编码直到自然数n。书的页码按照通常的习惯编排,每个页码都不含多余的前导数字0。例如,第6 页用数字6 表示,而不是06 或006 等。数字计数问题要求对给定书的总页码n,计算出书的全部页码中分别用到多少次数字0,1, 2,…,9。

编程任务:

  给定表示书的总页码的10 进制整数n (1≤n≤109) 。编程计算书的全部页码中分别用到多少次数字0,1,2,…,9。

数据输入:

  输入数据由文件名为input.txt 的文本文件提供。每个文件只有1 行,给出表示书的总页码的整数n。

结果输出: 

  程序运行结束时,将计算结果输出到文件output.txt 中。输出文件共有10 行,在第k 行输出页码中用到数字k-1 的次数,k=1,2,…,10。

输入文件示例         
input.txt  
11
输出文件示例
output.txt 
1 
4 
1 
1 
1 
1 
1 
1 
1 
1 

Algorithm thinking

A 10-bit integer stored array size of each digital number occurring for \ (1 \ sim n \) every number occurring, the last digit is obtained, by a number, all of the final output \ (0 \ sim 9 \) number to numbers.

Experimental Procedure

#include <bits/stdc++.h>
using namespace std;
const int maxn = 10;
int a[maxn];
void solve(int n)
{
    while(n)
    {
        ++a[n % 10];
        n /= 10;
    }
    return;
}
int main()
{
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    int n;
    scanf("%d", &n);
    memset(a, 0, sizeof a);
    for(int i = 1; i <= n; ++i)solve(i);
    for(int i = 0; i <= 9; ++i)printf("%d\n", a[i]);
}

Test Results

input:
11

output:
1 
4 
1 
1 
1 
1 
1 
1 
1 
1 

About the maximum number of questions

topic

问题描述:

  正整数x 的约数是能整除x 的正整数。正整数x 的约数个数记为div(x) 。例如,1,2, 5,10 都是正整数10 的约数,且div(10)=4 。设a 和b 是2 个正整数,a≤b,找出a 和b 之间约数个数最多的数x。

编程任务:

  对于给定的2 个正整数a≤b,编程计算a 和b 之间约数个数最多的数。

数据输入:

  输入数据由文件名为input.txt 的文本文件提供。文件的第1 行有2 个正整数a 和b。

结果输出: 

  程序运行结束时,若找到的a 和b 之间约数个数最多的数是x,将div(x)输出到文件output.txt 中。

输入文件示例                输出文件示例
input.txt                   output.txt 
 1 36                             9 

Algorithm thinking

Pretreatment all \ (1 \ sim maxn \) the number of each factor of the number, and then each test traversal \ (a \ sim b \) to identify the largest number of factors, to the output.

Experimental Procedure

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
int a[maxn];
void init()
{
    for(int i = 2; i <= maxn; ++i)
        for(int j = i; j <= maxn; j += i)
            ++a[j];
    return;
}
int main()
{
    // freopen("input.in", "r", stdin);
    // freopen("output.out", "w", stdout);
    init();
    int l, r;
    while(~scanf("%d%d", &l, &r))
    {
        int ans = 0;
        for(int i = l; i <= r; ++i)
            ans = max(ans, a[i]);
        printf("%d\n", ++ans);
    }
}

Test Results

input.txt                   output.txt 
 1 36                             9 

Dictionary order problem

topic

问题描述:

  在数据加密和数据压缩中常需要对特殊的字符串进行编码。给定的字母表A 由26 个小写英文字母组成A={a,b,…,z}。该字母表产生的升序字符串是指字符串中字母按照从左到右出现的次序与字母在字母表中出现的次序相同,且每个字符最多出现1 次。例如,a,b,ab,bc,xyz 等字符串都是升序字符串。现在对字母表A 产生的所有长度不超过6 的升序字符串按照字典序排列并编码如下。
1 2 
… 
26 27 28 
… 
a b 
… 
z ab ac 
… 
对任意长度不超过6 的升序字符串,迅速计算出它在上述字典中的编码。

编程任务:

  对于给定的长度不超过6 的升序字符串,编程计算出它在上述字典中的编码。

数据输入:
输入数据由文件名为input.txt 的文本文件提供文件的第一行是一个正整数k,表示接下来共有k 行接下来的k 行中,每行给出一个字符串。

结果输出: 

  程序运行结束时,将计算结果输出到文件output.txt 中。文件共有k 行,每行对应于一
个字符串的编码。
 
输入文件示例       输出文件示例
input.txt           output.txt 
2                      1 
a                      2 
b 

Algorithm thinking

1. Method to find the law recursive summation segment

After several strings hand Release number can be seen, it requires a number string, by \ (k-1 obtained long string + number of the last of a string of the first character of the current requirements lexicographic small, the number of all of the string of same length + length minus one and the same corresponding to the remaining characters of the string and the number of \) to obtain the number of strings to be required, there is clearly a common computing three operations: seeking All of a number of strings and string length len of the beginning of a defined \ (SUM (a, k) \) represents the number of characters in the string of length k as a beginning, apparently by all length \ ( k - 1 \) at the beginning of a character to be larger than the spliced with a character can be obtained, we find the length of \ (k - 1 \) begins with \ (a + 1 \ sim 26 \) is the number of all strings and we can obtain the length \ (K \) and the beginning of a number of strings, that is to say: \ (SUM (a, K) = \ sum_ {I} = a +. 1} ^ {SUM 26 is (I ,. 1-K) \) , this may be obtained by a recursive manner.

So the whole problem is the result of the process:

  • A string is calculated for all of the k-1 number (in this case starts with the letter all) 26 calls sum () function
  • All begin with the character length is calculated to be less than required for the beginning of a string of characters of the character string k: call \ (a-1 \) times sum () function
  • Calculate the length of \ (k-1 \) and followed by several character string to be less than that of a character string corresponding to the request and

E.g:

s: cefvz

  • First of all determined lengths less than the number 5, that is: \ ( 'A' \ SIM \ 'wxyz' \) number
  • Obtaining \ ( 'abcde' \ sim \ 'bwxyz' \) the number of this section is to compute the length of 5, beginning less than 'c' of the string
  • Obtaining \ ( 'cdefg' \ sim \ 'cefvz' \) number of this section is to compute the length from the number of all strings 'defg' to 'efvz' of the k-1 = 4
2. Violence Act deep search save hash dictionary

Because the required maximum length of the title character string given only 6, the searched-out character string can be deep all qualified, (DFS is the sequence number of the string), then for each given a hash value string, Finally, for each inquiry based on hash string of numbers can be derived. (Test data can be generated by this method)

Experimental Procedure

Act 1
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
char s[10];

int sum(int i, int j)
{
    int ret = 0;
    if(j == 1)return 1;
    else
    {
        for(int k = i + 1; k <= 26; ++k)
            ret += sum(k, j - 1);
    }
    return ret;
}
void solve()
{
    int ans = 0;
    int len = strlen(s);
    for(int i = 1; i <= len - 1; ++i)
        for(int j = 1; j <= 26; ++j)
            ans += sum(j, i);
    // cout << ans << "--" << endl;
    for(int i = 1; i <= s[0] - 'a' + 1 - 1; ++i)
        ans += sum(i, len);
    // cout << ans << "--" << endl;
    for(int i = 1; i <= len - 1; ++i)
    {
        for(int j = s[i - 1] - 'a' + 1 + 1; j <= s[i] - 'a' + 1 - 1; ++j)
            ans += sum(j, len - i);
    }
    printf("%d\n", ++ans);
}

int main()
{
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);

    int t;scanf("%d", &t);
    while(t--)
    {
        scanf("%s", &s);
        solve();
    }
    return 0;
}
Act 2
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
char s[10];
const int p = 1e3+7;
unordered_map<int, int> mp;
inline int gethash(int len)
{
    int ret = 1;
    for(int i = 0; i <= len - 1; ++i)
        ret += ret * p + s[i] - 'a';
    return ret;
}
int tot = 0;
void print(int len, int n)
{
    if(n == len)
    {
//        printf("%s", s);
        // for(int i = 0; i < len; ++i)printf("%c", s[i]);
        // printf("\n");
        mp[gethash(len)] = ++tot;
        return;
    }
    if(n == 0)
    {
        for(int i = 0; i < 26; ++i)
        {
            s[0] = (char)(i + 'a');
            print(len, n + 1);
        }
    }
    else
    {
        for(int i = 0; i < 26; ++i)
        {
            if(s[n - 1] < i + 'a')
            {
                s[n] = (char)(i + 'a');
                print(len, n + 1);
            }
        }

    }

    return;
}
void init()
{
    tot = 0;
    for(int i = 1; i <= 6; ++i)
        print(i, 0);
}

int main()
{
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);

    init();
    int t;scanf("%d", &t);
    while(t--)
    {
        scanf("%s", &s);
        printf("%d\n", mp[gethash(strlen(s))]);
    }
    return 0;
}

Test Results

input:
4
abc
bciop
acfuxz
uvwxyz

output:
352
31577
98306
313911

how are you

Storage procedures

topic

算法实现题     程序存储问题

问题描述:

  设有n 个程序{1,2,…, n }要存放在长度为L 的磁带上。程序i 存放在磁带上的长度是li,1≤i≤n 。程序存储问题要求确定这n 个程序在磁带上的一个存储方案,使得能够在磁带上存储尽可能多的程序。

编程任务:

  对于给定的n 个程序存放在磁带上的长度,编程计算磁带上最多可以存储的程序数。

数据输入:

  由文件input.txt 给出输入数据。第一行是2 个正整数,分别表示文件个数n 和磁带的长度L。接下来的1 行中,有n 个正整数,表示程序存放在磁带上的长度。

结果输出: 

  将编程计算出的最多可以存储的程序数输出到文件output.txt 。

输入文件示例输出文件示例
input.txt                        output.txt 
6 50                                  5
2 3 13 8 80 20

Algorithm thinking

Because you want to maximize the number of storage, so give priority to small storage space.

After sorting and taking the front space equal to just less than the maximum number of spaces.

Experimental Procedure

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
int a[maxn];
void solve()
{
    int n, l;
    scanf("%d%d", &n, &l);
    for(int i = 1; i <= n; ++i)scanf("%d", &a[i]);
    sort(a + 1, a + 1 + n);
    int ans = 0;
    int sum = 0;
    for(int i = 1; i <= n; ++i)
    {
        sum += a[i];
        if(sum <= l)++ans;
        else break;
    }
    printf("%d\n", ans);
    return;
}
int main()
{
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);

    solve();
    return 0;
}

Test Results

input:
6 50                                 
2 3 13 8 80 20

output:
5

Car refueling

topic

算法实现题    汽车加油问题

问题描述:

  一辆汽车加满油后可行驶n 公里。旅途中有若干个加油站。设计一个有效算法,指出应在哪些加油站停靠加油,使沿途加油次数最少。并证明算法能产生一个最优解。

编程任务:

  对于给定的n 和k 个加油站位置,编程计算最少加油次数。

数据输入:

  由文件input.txt 给出输入数据。第一行有2 个正整数n 和k,表示汽车加满油后可行驶n 公里,且旅途中有k 个加油站。接下来的1 行中,有k+1 个整数,表示第k 个加油站与第k-1 个加油站之间的距离。第0 个加油站表示出发地,汽车已加满油。第k+1 个加油站表示目的地。

结果输出: 

  将编程计算出的最少加油次数输出到文件output.txt 。如果无法到达目的地,则输出”No Solution”。

输入文件示例输出文件示例
input.txt                       output.txt 
7 7                                  4
1 2 3 4 5 1 6 6

Algorithm thinking

Greedy consider refueling, when the current is not enough fuel remaining to reach the next stop, in which a petrol station, or go all the way.

Experimental Procedure

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
int n, k, a[maxn];
int main()
{
    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);
    cin >> n >> k;
    for(int i = 0; i <= k; ++i)cin >> a[i];
    int ans = 0;
    for(int i = 1; i <= k; ++i)
    {
        int sum = 0;
        int nxt = i;
        for(nxt = i; nxt <= k; ++nxt)
        {
            sum += a[nxt];
            if(sum > n)break;
        }
        if(i == nxt)
        {
            cout << "No Solution" << endl;
            return 0;
        }
        i = nxt - 1;
        ++ans;
        if(nxt == k + 1)break;
    }
    cout << ans - 1 << endl;
    return 0;
}

Test Results

input:
7 7
1 2 3 4 5 1 6 6

output;
4

Optimal decomposition problem

topic

算法实现    最优分解问题

问题描述:

  设n 是一个正整数。现在要求将n 分解为若干个互不相同的自然数的和,且使这些自然数的乘积最大。

编程任务:

  对于给定的正整数n,编程计算最优分解方案。

数据输入:

  由文件input.txt 提供输入数据。文件的第1 行是正整数n。

结果输出: 

  程序运行结束时,将计算出的最大乘积输出到文件output.txt 中。

输入文件示例         输出文件示例
input.txt            output.txt 
10                      30 

Algorithm thinking

If \ (n = I + J \) , when the \ (ij of \) when very close, then \ (i * j \) maximum, the first decomposed into n \ (a = {2 + 3 + 4 +. .. + k} \) and \ (\ SUM a <= n-\) , for a part of the extra number, plus one for every backwards, the final product of the maximum guaranteed.

Experimental Procedure

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
int a[maxn];
int n;
void solve()
{
    for(int i = 1; i * i / 4 <= n; ++i)
        a[i] = i;
    int sum = 0;
    int last;
    for(int i = 2; i * i / 4 <= n; ++i)
    {
        sum += a[i];
        if(sum >= n)
        {
            sum -= a[i];
            sum = n - sum;
            last = i - 1;
            break;
        }
    }
    while(sum)
    {
        ++a[last];
        --sum;
        if(!sum)break;
        for(int i = last; i >= 2; --i)
        {
            --sum;
            ++a[i];
            if(!sum)break;
        }
    }
    int ans = 1;
    for(int i = 2; i <= last; ++i)ans *= a[i];
    cout << ans << endl;
    return;
}
int main()
{
    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);
    while(~scanf("%d", &n))
        solve();
    return 0;
}

Test Results

intut:
10

output:
30

Recursion and divide and conquer strategy

The number of public issues

topic

算法实现题    众数问题

问题描述:

  给定含有n 个元素的多重集合S,每个元素在S 中出现的次数称为该元素的重数。多重集S 中重数最大的元素称为众数。
  
例如,S={1,2,2,2,3,5}。
多重集S 的众数是2,其重数为3。

编程任务:

  对于给定的由n 个自然数组成的多重集S,编程计算S 的众数及其重数。

数据输入:

  输入数据由文件名为input.txt 的文本文件提供。文件的第1 行多重集S 中元素个数n;接下来的n 行中,每行有一个自然数。

结果输出: 

  程序运行结束时,将计算结果输出到文件output.txt 中。输出文件有2 行,第1 行给出众数,第2 行是重数。

输入文件示例          输出文件示例
input.txt             output.txt 
6                      2 
1                      3 
2 
2 
2 
3 
5 

Algorithm thinking

Sorted binary search the number of occurrences of each number, to record the maximum value.

Experimental Procedure

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
int a[maxn];
int ans, ansn;
int n;
void solve()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i)scanf("%d", &a[i]);
    int l, r;
    l = r = 1;
    int t;
    sort(a + 1, a + 1 + n);
    ans = ansn = 0;
    for(int i = 1; i <= n; ++i)
    {
        l = lower_bound(a + 1, a + 1 + n, a[i]) - a - 1;
        r = upper_bound(a + 1, a + 1 + n, a[i]) - a - 1;
        t = r - l;
        if(t >= ansn)
        {
            ans = a[i];
            ansn = t;
            i = r;
        }
    }
    printf("%d\n%d\n", ans, ansn);
    return;
}
int main()
{
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);

    solve();
    return 0;
}

Test Results

input: 
6                      
1                      
2 
2 
2 
3 
5 

output:
2
3

Integer factorization problem

topic

算法实现题    整数因子分解问题

问题描述:

 大于1 的正整数n 可以分解为:n=x1*x2*…*xm。
例如,当n=12 时,共有8 种不同的分解式:
12=12;
12=6*2;
12=4*3;
12=3*4;
12=3*2*2;
12=2*6;
12=2*3*2;
12=2*2*3 。

编程任务:

  对于给定的正整数n,编程计算n 共有多少种不同的分解式。

数据输入:

  由文件input.txt 给出输入数据。第一行有1 个正整数n (1≤n≤2000000000)。

结果输出: 

将计算出的不同的分解式数输出到文件output.txt 。

输入文件示例          输出文件示例
input.txt            output.txt 
 12                      8 

Algorithm thinking

Violence recursively to find out every possible decomposition due to type, you can count. (Such an approach for some integer greater than 1e7 may exceed 1s)

Experimental Procedure

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ans, n;
void solve(ll x)
{
    if(x == 1)
        ++ans;
    else
        for(int i = 2; i <= x; ++i)
            if(!(x % i))
                solve(x / i);
}
int main()
{
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);

    while(cin >> n)
    {
        ans = 0;
        solve(n);
        cout << ans << endl;
    }
    return 0;
}

Test Results

intput:
12
100
233
123456
10000000

output:
8
26
1
2496
3112896

Guess you like

Origin www.cnblogs.com/31415926535x/p/10963938.html