首页 > 代码库 > 算法设计与分析 ------最近对问题与8枚硬币问题

算法设计与分析 ------最近对问题与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             P1[k2++].x = points[i].x;
117             P1[k2++].y = points[i].y;
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 }