假幣演算法求解(三分演算法和二分演算法)

來源:互聯網
上載者:User
 //**********************************************
//
//        假幣演算法求解(三分演算法和二分演算法)
//             xwlee 2006/12/20
//**********************************************
#include<iostream>
#include<cmath>
#include <ctime>
#include <iomanip>
using namespace std;

int find2(int coin[], int low, int high);//二分演算法
int find3(int coin[], int low, int high);//三分演算法

int  main(void)
{
    int i, *coin,n,temp;
 
    cout<<"請輸入硬幣的個數(n最大為機器整數值):";
    cin>>n;
    srand( (unsigned)time( NULL ) );//srand()函數產生一個以目前時間開始的隨機種子
    cout<<"正在隨機產生資料(用0和1分別代表假幣和真幣).../n/n";
    coin=new int[n+1];//多產生一個位置,用coin[0]來記錄本次調用稱重的次數
    temp=1+rand()%n;//隨機產生1~n之間的一個數
    coin[0]=0;//計數器
    for(i=1; i<n+1; ++i)
        i!=temp ? coin[i]=1 : coin[i]=0;
            
    for(i=1; i<n+1; ++i)
        if(i!=temp)
            cout<<"第"<<setw(3)<<i<<" 枚硬幣是真幣(1)"<<endl;
        else
            cout<<"第"<<setw(3)<<i<<" 枚硬幣是假幣(0)"<<endl;
        
        cout<<endl<<endl<<"假幣二分演算法結果:"<<endl;
        cout<<"假幣在第"<<setw(3)<<find2(coin,1,n)<<"個位置!"<<endl;
        cout<<"總共稱的次數為"<<setw(3)<<coin[0]<<"次!"<<endl;
       
        cout<<endl<<endl<<"假幣三分演算法結果:"<<endl;
        cout<<"假幣在第"<<setw(3)<<find3(coin,1,n)<<"個位置!"<<endl;
        cout<<"總共稱的次數為"<<setw(3)<<coin[0]<<"次!"<<endl<<endl<<endl;
    
    return 0;
}

int find2(int coin[], int low, int high)
{
    int i,mid,sum1,sum2,sign;
    
    coin[0]=0;
    do //下界和上界所指示的初始位置
    {
             mid=(low+high)/2;
             sign= (low+high)%2;//標記奇數和偶數
             //cout<<sign<<endl;
             sum1=sum2=0;

             if(sign==0)//處理奇數的情況
             {    
                 for(i=low; i<mid; i++)
                    sum1 += coin[i];
                  for(i=mid+1; i<=high; i++)
                    sum2 += coin[i];
          
                  if( sum1==0 && sum2==0  )
                   ;
                 else
                    coin[0] += 1;

                 if(sum1==sum2)  
                    return mid;
                 else if(sum1<sum2)  
                 {
                    high=mid-1;
                 }
                 else  
                 {
                    low=mid+1;
                 }
            
             }
              else//處理偶數的情況
             {
                 for(i=low; i<=mid; i++)
                    sum1 += coin[i];
                 for(i=mid+1; i<=high; i++)
                    sum2 += coin[i];
                 if( sum1==0 && sum2==0  )
                   ;
                 else
                    coin[0] += 1;
                 if(sum1<sum2)  
                    high=mid;
                 else  
                    low=mid+1;
            }
              
    }while(1);//end while
   
    return -1;
}

int find3(int coin[], int low, int high)
{
    int i,mid1,mid2,sum1,sum2,sum3,flag,my_space;
    
    coin[0]=0;

    if(high<3)
        {cout<<"您必須鍵入的個數要大於3"<<endl<<endl<<endl; exit(1);}
    while(low<=high) //下界和上界所指示的初始位置
    {
             sum1=sum2=sum3=0;
             my_space=(high-low+1)/3;     
              mid1=low+my_space-1;
             mid2=mid1+my_space;
             flag= (high-low+1) % 3;//標記被3除的餘數,分別是餘數為0,1,2
            
             for(i=low; i<=mid1; i++)
                 sum1 += coin[i];
             for(i=mid1+1; i<=mid2; i++)
                 sum2 += coin[i];
             for(i=mid2+1; i<=mid2+my_space; i++)  //注意這裡
                 sum3 += coin[i];
             if( sum1==0 && sum2==0 && sum3==0 )
              ;
             else
                 coin[0] += 1;
             if(flag==0)//處理餘數為0的情況
             {
                    if(sum1==sum2)
                     low=mid2+1;
                 if(sum1==sum3)
                 {   low=mid1+1; high=mid2; }
                 if(sum2==sum3)
                     high=mid1;
             }
            else if(flag==1)////處理餘數為1的情況
            {
                 if( sum1==sum2)
                 {
                      if(sum1==sum3)
                      { return high;}
                      else
                      {low=mid2+1; high=high-1;}
                 }
                 else
                 {
                      if(sum1==sum3)
                      { low=mid1+1; high=mid2;}
                      if(sum2==sum3)
                      { high=mid1; }
                
                 }

            }    
             else////處理餘數為2的情況
             {
                      
                 
                 if( sum1==sum2)
                 {
                      if(sum1==sum3)
                      {
                          coin[0] += 1;
                           if(coin[high-1]==0)
                               return high-1;
                           else
                               return high;
                      
                      }
                      else
                      {low=mid2+1; high=high-2;}
                 }
                 else
                 {
                      if(sum1==sum3)  
                      { low=mid1+1; high=mid2;}
                      if(sum2==sum3)
                      { high=mid1; }
                 }
            }
            //coin[0] += 1;
            
    }//end while
   
    return -1;
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.