zoukankan      html  css  js  c++  java
  • 分治法习题

    一.分治法设计一个算法,统计输入的非空字符串中给定字符的个数。

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 using namespace std;
     5 const int maxn = 1000;
     6 char str[maxn];
     7 char TargetChar;
     8 int CharNum;
     9 int CountTargetCharNum(char s[], char TargetChar, int begin, int end)
    10 {
    11     int L, R;
    12     if(begin == end) return (s[begin] == TargetChar);
    13     else
    14     {
    15         L = CountTargetCharNum(s, TargetChar, begin, begin + (end - begin)/2);
    16         R = CountTargetCharNum(s, TargetChar, begin + (end - begin)/2 + 1, end);
    17         return (L + R);
    18     }
    19 }
    20 
    21 int main()
    22 {
    23     cout<<"Please enter a string:";
    24     gets(str);
    25     if(strlen(str) == 0)
    26     {
    27         cout<<"Don't allow to enter a NULL string!"<<endl;
    28         return 0;
    29     }
    30     cout<<"Please enter a char what you need to find:";
    31     cin>>TargetChar;
    32     CharNum = CountTargetCharNum(str, TargetChar, 0, maxn - 1);
    33     cout<<"Finding the char number:"<<CharNum<<endl;
    34     return 0;
    35 }

    二.非递归形式设计二分搜索程序。

     1 int BinarySearch(int ArrayData[], int x, int n)
     2 {
     3     int L = 0, R = n - 1;
     4     while(L <= R)
     5     {
     6         int mid = (L + R)/2;
     7         if(x == ArrayData[mid]) return mid;
     8         if(x > ArrayData[mid]) L = mid + 1;
     9         else R = mid - 1;
    10     }
    11     return -1; //未找到 x
    12 }

    三.16个硬币放袋子里,其中有一枚硬币是假币,并且那个伪造的硬币比真币轻,设计一个算法找到那枚假币。

     1 #include <bits/stdc++.h>
     2 #define ARRAY_SIZE 16
     3 #define TRUE 1
     4 #define FALSE 0
     5 using namespace std;
     6 int CallTimes = 0;
     7 //生成包含 N 个硬币重量的数组(含一枚伪币),并返回伪币位置
     8 int GreateRandomCoinWeightArray(int *p, int N)
     9 {
    10     int i, kt;
    11     int TrueCoinWeight, FakeCoinWeight;
    12     int IsStop;
    13     //生成随机数种子
    14     srand((unsigned)time(NULL));
    15     //生成随机真币重量值(在 50 ~ 100 之间)
    16     TrueCoinWeight = 50 + rand()%(100 - 50);
    17     //生成随机伪币位置(在 0 ~ N - 1 之间)
    18     kt = rand() % N;
    19     //设置真币重量
    20     for(i = 0; i < N; i++)
    21         if(i != kt)
    22             *(p + i) = TrueCoinWeight;
    23     //生成一个比真币略轻的伪币重量
    24     IsStop = FALSE;
    25     while(!IsStop)
    26     {
    27         FakeCoinWeight = 50 + rand()%(100 - 50);
    28         //
    29         if((TrueCoinWeight > FakeCoinWeight) && (TrueCoinWeight - FakeCoinWeight <= 5))
    30         {
    31             IsStop = TRUE;
    32             *(p + kt) = FakeCoinWeight;
    33         }
    34     }
    35     //返回伪币位置
    36     return kt;
    37 }
    38 //计算数组中硬币的重量和
    39 int CalcCoinTotalWeight(int ArrayData[], int kb, int ke)
    40 {
    41     int i, TotalWeight = 0;
    42     for(i = kb; i <= ke; i++) TotalWeight += ArrayData[i];
    43     return TotalWeight;
    44 }
    45 //采用分治法找到伪币(假定伪币一定存在且只有一枚)
    46 //kb:(子)数组左边界( begin )
    47 //ke:(子)数组右边界( end )
    48 int FindFakeCoin(int ArrayData[], int kb, int ke)
    49 {
    50     int LWeight, RWeight;
    51     CallTimes++;
    52     printf("<第 %d 次查找>
    ",CallTimes);
    53     if((ke - kb) == 1)  //(子)数组中仅包含两个元素
    54     {
    55         if(ArrayData[kb] < ArrayData[ke]) return kb;
    56         else return ke;
    57     }
    58     else //(子)数组中包含有多个元素
    59     {
    60         //计算子数组硬币重量
    61         LWeight = CalcCoinTotalWeight(ArrayData, kb, kb + (ke - kb)/2);  
    62         RWeight = CalcCoinTotalWeight(ArrayData,kb + (ke - kb)/2 + 1, ke);
    63         if(LWeight < RWeight)  //伪币在数组左半部分
    64             return FindFakeCoin(ArrayData, kb, kb + (ke - kb)/2);
    65         else      //伪币在数组右半部分
    66             return FindFakeCoin(ArrayData, kb + (ke - kb)/2 + 1, ke);
    67     }
    68 }
    69 int main()
    70 {
    71     int ArrayData[ARRAY_SIZE];
    72     int i, k, FakeCoinPos;
    73     //生成包含 N 个硬币重量的数组(含一枚伪币),并返回伪币位置
    74     k = GreateRandomCoinWeightArray(ArrayData, ARRAY_SIZE);
    75     //输出随机数组内容
    76     printf("<生成的硬币重量数组值为(含一枚伪币)>:
    ");
    77     for(i = 0; i < ARRAY_SIZE; i++) printf("%d
    ",ArrayData[i]);
    78     printf("
    ");
    79     printf("<第 %d 枚为伪币>
    ",(k + 1));
    80     printf("
    ");
    81     //采用分治法找到伪币位置
    82     FakeCoinPos = FindFakeCoin(ArrayData, 0, ARRAY_SIZE - 1);
    83     printf("<找到第 %d 枚伪币>
    ",(FakeCoinPos+1));
    84     printf("
    ");
    85     //等待用户输入任意一键返回
    86     system("PAUSE");
    87     return 0;
    88 }

    四. 大于 1 的正整数 n,设计一个算法计算 n 有多少种不同的分解式。

     1 int TotalModeNum = 0;
     2 int CalcIntDecomModeNum(int n)
     3 {
     4     if(n == 1) TotalModeNum++;
     5     else
     6     {
     7         for(int i = 2; i <= n; i++)
     8             if(n % i == 0)
     9                 CalcIntDecomModeNum(n/i);
    10     }
    11 }

    五.给定 a, 分治法设计出 a^n 的算法

    1 double CalcPow(double a, int n)
    2 {
    3     if(n == 0) return 1.0;
    4     double b = CalcPow(a, n/2);
    5     b *= b;
    6     if(n%2==1) b *= a;   // 处理奇数次幂的情况
    7     return b;
    8 }

    六.给定两个长度相等的数组,分治算法求出合并后的排序数组的中位数。

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <stdlib.h>
     4 #include <string.h>
     5 using namespace std;
     6 const int maxn = 1000;
     7 int a[maxn], b[maxn];
     8 int CalcMedian(int a[], int n)
     9 {
    10     if(n%2 == 0)
    11         return (a[n/2] + a[n/2-1])/2;
    12     else
    13         return a[n/2];
    14 }
    15 
    16 int CalcArrayMedian(int A[], int B[], int n)
    17 {
    18     int m1, m2;
    19     if(n <= 0) return -1;
    20     if(n == 1) return (A[0] + B[0])/2;
    21     if(n == 2) return (max(A[0], B[0]) + min(A[1], B[1]))/2;
    22 
    23     m1 = CalcMedian(A, n);
    24     m2 = CalcMedian(B, n);
    25 
    26     if(m1 == m2) return m1;
    27     if(m1 < m2)
    28     {
    29         if(n%2 == 0) return CalcArrayMedian(A + n/2 - 1, B, n/2 + 1);
    30         else return CalcArrayMedian(A + n/2, B, n/2+1);
    31     }
    32     else
    33     {
    34         if(n%2 == 0) return CalcArrayMedian(B + n/2 - 1, A, n/2 + 1);
    35         else return CalcArrayMedian(B + n/2, A, n/2 + 1);
    36     }
    37 }
    38 int main()
    39 {
    40     int m;
    41     cin>>m;
    42     for(int i = 0; i < m; i++) cin>>a[i];
    43     for(int i = 0; i < m; i++) cin>>b[i];
    44     int mid = CalcArrayMedian(a,b,m);
    45     cout<<mid<<endl;
    46     return 0;
    47 }
  • 相关阅读:
    hdu 1286
    hdu 1420
    hdu 2068
    hdu 1718
    hdu 1231
    hdu 1072
    HDOJ 350留念
    hdu 1898
    hdu 1593
    帮助理解git的图
  • 原文地址:https://www.cnblogs.com/Edviv/p/11627444.html
Copyright © 2011-2022 走看看