算法设计与分析 ------最近对问题与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 }