zoukankan      html  css  js  c++  java
  • 算法设计与分析 ------最近对问题与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 }
  • 相关阅读:
    Ajax组件(wagang版)
    动画组件(wagang版)之基础篇:跳帧与延时
    Ajax组件(wagang版)之无依赖化
    ✍23 postgresql批量删除表
    ✍20 samba共享服务
    ✍16 asyncio异步IO
    ✍19 Tensonfow(GPU)使用
    ✍25 mysqlclient 安装(linux,mac)
    ✍17 aiohttp模块的使用
    ✍18 Linnux上安装node.js
  • 原文地址:https://www.cnblogs.com/zhuxuekui/p/3698164.html
Copyright © 2011-2022 走看看