算法设计与分析 ------最近对问题与8枚硬币问题

 利用减治法实现8枚硬币问题:

参考资料:http://blog.csdn.net/wwj_748/article/details/8863503    算法设计--八枚硬币问题

 1 #include "stdafx.h"

 2 #include <iostream>

 3 #include <stdio.h>

 4 using namespace std;

 5 

 6 

 7 void eightcoin(int arr[]);

 8 void compare(int a,int b,int real,int index1,int index2);//这句话是为了在两个当中比较谁真,谁假。

 9 void print(int jia,int zhen,int i);//这句话是为了输出在某个位置的假硬币的信息。

10 int main()

11 {

12     int arr[8];

13     //分别输入8枚硬币的重量

14     while(1)

15     {

16         for(int i=0; i<8; ++i)

17         {

18             cin >> arr[i];

19         }

20         eightcoin(arr);

21     }    

22     return 0;

23 }

24 void eightcoin(int arr[])

25 {

26     int abc = arr[0] + arr[1] + arr[2];

27     int def = arr[3] + arr[4] + arr[5];

28     int a = arr[0];

29     int b = arr[1];

30     int c = arr[2];

31     int d = arr[3];

32     int e = arr[4];

33     int f = arr[5];

34     int g = arr[6];

35     int h = arr[7];

36 

37     if (abc > def) //6枚硬币必有一枚假币,g,h为真币 

38     {

39         if ((a+e) > (d+b))//去掉c,f,且b,e互换后,没有引起天平变化,说明假币必然是a,d中的一个  

40         {

41             compare(a,d,g,0,3);

42         }

43         else if ((a+e) == (d+b))

44         {

45             compare(c,f,g,2,5);

46         }

47         else 

48         {

49             compare(b,e,g,1,4);

50         }

51     }

52     else if (abc == def)

53     {

54             compare(g,h,a,6,7);   

55     }

56     else

57     {

58         if ((a+e) > (d+b))

59         {

60             compare(b,e,g,1,4);

61         }

62         else if ((a+e) == (d+b))

63         {

64             compare(c,f,g,2,5);

65         }

66         else 

67         {

68             compare(a,d,g,0,3);

69         }

70     }

71 }

72 

73 

74 

75 void compare(int a,int b,int real,int index1,int index2)

76 {

77     if( a > real)

78         print(a,real,index1);

79     else

80         print(b,real,index2);

81 }

82 void print(int jia,int zhen,int i)

83 {

84     if (jia > zhen)

85     {

86         cout << "位置在:"<< i+1 << "是假币" << "且较重!" << endl;

87     }

88     else

89     {

90         cout << "位置在:"<< i+1 << "是假币" << "且较轻!" << endl;

91     }

92 }

 

 

 

 

利用蛮力法与分治法实现最近对问题:

参考资料:http://wenku.baidu.com/link?url=49Zq90UzxulQCJTtKfgum_6lAohBWHnynyr7jbHlXrT0z1SGIFLkJZYEPkuKrZ9aMjJLf0EZQfvjrL3b9QksbFKO6hsist_HDOT1gV72nVe

 

http://blog.sina.com.cn/s/blog_6364615e0100o67v.html

 参考了我前面的一篇日志,sort的用法。

  1 // ClosestPoints.cpp : 定义控制台应用程序的入口点。

  2 //

  3 

  4 #include "stdafx.h"

  5 #include <Windows.h>

  6 #include <time.h>

  7 #include <math.h>

  8 #include <iostream>

  9 #include <algorithm>

 10 using namespace std;

 11 typedef struct Point   //定义数据结构

 12 {

 13    long x;

 14    long y;

 15 } Point;

 16 Point points[200],P1[100],P2[100];

 17 const long MAX = 6000000;

 18 

 19 int cmp(Point a, Point b)   //对平面内的坐标进行有规则的排序

 20 {

 21    if (a.x != b.x)

 22    {

 23        return a.x < b.x;

 24    }

 25    else

 26    {

 27        return a.y < b.y;

 28    }

 29 }

 30 

 31 int cmp2(Point a, Point b)   //升序排列

 32 {

 33     return a.y < b.y;

 34 }

 35 long Distance(Point a,Point b)

 36 {

 37     long dist = (a.x - b.x)*(a.x - b.x) + (a.y - a.y)*(a.y - b.y);

 38     return dist;

 39 }

 40 

 41 //int min1(int a,int b)

 42 //{

 43 //    if (a>b)

 44 //    {

 45 //        return b;

 46 //    }

 47 //    else

 48 //    {

 49 //        return a;

 50 //    }

 51 //}

 52 //蛮力法,每个都找一遍,两两寻找

 53 long ClosestPoints(Point points[],int n,int *index1,int *index2)

 54 {

 55     long minDist = MAX;

 56     long Dist = 0;

 57     for (int i=0; i<n; ++i)

 58    {

 59        for (int j=i+1; j<n; ++j)

 60        {

 61            Dist = Distance(points[i],points[j]);

 62            if (Dist < minDist)

 63            {

 64                minDist = Dist;

 65                *index1 = i;

 66                *index2 = j;

 67            }

 68        }

 69    }

 70     return minDist;

 71 }

 72 

 73 

 74 //分治法函数

 75 long DivPoints(Point points[],int begin,int end)

 76 {

 77    int n = end - begin + 1;

 78    int m = (end + begin)/2;

 79    if (n == 2)

 80    {

 81        return Distance(points[begin],points[end]);

 82    }

 83    if (n == 3)   //三者当中找最小

 84    {

 85        long d1 = Distance(points[begin],points[begin+1]);

 86        long d2 = Distance(points[begin],points[end]);

 87        long d3 = Distance(points[begin+1],points[end]);

 88        if (d1<=d2 && d1<= d3)

 89        {

 90            return d1;

 91        }

 92        else if (d2 <= d3)

 93        {

 94            return d2;

 95        }

 96        else 

 97            return d3;

 98    }

 99    long left = DivPoints(points,begin,m);

100    long right = DivPoints(points,m+1,end);

101    long d = min(left,right);

102    int k1 = 0, k2 = 0;

103    for (int i = begin ; i <= m; ++i)      //中位数的左边区域

104    {

105         if (points[m].x - points[i].x<sqrt((float)d))

106         {

107             P1[k1].x = points[i].x;

108             P1[k1].y = points[i].y;

109             k1++;//在有两个以上的变量进行赋值的时候,不能用这个。而用此赋值方法

110         }

111    }

112    for (int i = m + 1 ; i <= end; ++i)   //中位数的右边区域,分割成两个P1与P2数组

113    {

114         if (points[i].x - points[m].x<(int)sqrt((float)d))

115         {

116             P2[k2].x = points[i].x;

117             P2[k2].y = points[i].y;
k2++;
118 } 119 } 120 121 //page 90 ,需要依据y进行升序排列,然后两两比较,找出最小 122 sort(P1,P1+k1,cmp2); 123 sort(P2,P2+k2,cmp2); 124 long dist=0; 125 long dMin=MAX; 126 for (int i = 0; i < k1 ; ++i) //排序之后找里面最小的,这个部分是合并部分的工作。 127 { 128 for (int j = 0; j < k2; ++j) 129 { 130 dist = Distance(P1[i],P2[j]); 131 dMin = min(dist,dMin);//递归求最小距离 132 } 133 } 134 135 136 137 //int k,l,flag=0;//k与l分别是记录左右两边<d的点的位置 138 ////找到以m为中心与m横坐标距离小于sqrt(d)的点 139 //for(int i = begin; i <= end; ++i) 140 //{ 141 // if (flag == 0 && (points[m].x - points[i].x<sqrt(d)))//遍历左半部分 142 // { 143 // flag = 1; 144 // k = i; 145 // } 146 // if (flag == 1 &&(points[i].x - points[m].x<sqrt(d)))//遍历右半部分 147 // { 148 // l = i; 149 // } 150 //} 151 //for (i = k ; i <= m; ++i) 152 //{ 153 // for (j=m+1; j<=1 && fabs((points[j].y-points[i].y)<sqrt(d)); ++j) 154 // { 155 // if (Distance(points[i],points[j]) <= d) 156 // { 157 // d = Distance(points[i],points[j]); 158 // } 159 // } 160 //} 161 return min(d,dMin); //比较d与dMin的大小,并返回,合并。 162 } 163 164 165 166 int _tmain(int argc, _TCHAR* argv[]) 167 { 168 169 LARGE_INTEGER frequency,begin,end; 170 171 while (1) 172 { 173 int n; 174 cout << "随机生成n个点"<<endl; 175 cin >> n; 176 cout << "随机生成"<<n<<"个点的X与Y坐标如下:"<<endl; 177 /* 178 srand()的功能就是就是设置产生随机数的公式的参数(随机数种子),如果使用相同的种子, 179 那么得到的随机数也就是相同的。自然,如果使用不同的种子,得出的随机数序列也是不同的。 180 不同的种子会得到 固定 的 不同的随机数序列。 181 */ 182 srand((unsigned int)time(0));//产生不同的随机数 183 for (int i=0; i<n;++i) 184 { 185 points[i].x = rand(); 186 points[i].y = rand(); 187 cout << points[i].x << "," << points[i].y <<" "; 188 } 189 cout << endl; 190 191 int index1 = 0; 192 int index2 = 0; 193 QueryPerformanceFrequency(&frequency); 194 QueryPerformanceCounter(&begin); 195 long minDist = ClosestPoints(points,n,&index1,&index2); 196 QueryPerformanceCounter(&end); 197 cout << "蛮力法所用时间为"<< (double)(end.QuadPart - begin.QuadPart)/frequency.QuadPart<<endl; 198 cout << "最短距离为"<< minDist <<endl; 199 /*cout << points[index1].x << " "<< points[index1].y << endl; 200 cout << points[index2].x << " "<< points[index2].y << endl;*/ 201 202 203 QueryPerformanceFrequency(&frequency); 204 QueryPerformanceCounter(&begin); 205 206 sort(points,points+n,cmp);//当成数组 207 minDist = DivPoints(points,0,n-1); 208 QueryPerformanceCounter(&end); 209 cout << "分治法所用时间为"<< (double)(end.QuadPart - begin.QuadPart)/frequency.QuadPart<<endl; 210 cout << "最短距离为"<< minDist <<endl; 211 212 } 213 return 0; 214 }

 

 

你可能感兴趣的:(算法)