---
# System prepended metadata

title: 演算法作業HW1
tags: [演算法]

---

###### tags: `演算法`
# 演算法作業HW1
## 1.本週影片中提到的NP-complete問題有哪些？
 
- 0/1 Knapsack problem
- Traveling salesperson problem
- partition problem
- Art gallery problem
## 2. 請上網找一個老師沒說過的NP-complete問題，並舉個例子說明該問題的輸入與輸出。
- 採地雷
    -   因為我們要知道這個格子安不安全，要先知道整格盤面的狀況，幾乎是把整個盤面還沒開的格子檢查一遍，就是暴力解，在條件充足下用數字去做比對，如果未知的方塊中沒有地雷，就表示安全，如果一行出現121這個數字表示具有唯一解，地雷都在兩個1的旁邊，出現1221地雷只會出現在2的旁邊，還有其他的例如212、2112、211112、2111112、122221，在已知條件不足下只能用猜測的。
    -   輸入:找出具有唯一解的組合
    -   輸出:標示出所有地雷
   ![](https://i.imgur.com/74QOQN9.png)
## 二元搜尋法-Leecode704(自己練習)
   1.程式碼
   ``` C++=
class Solution {
public:
int search(vector<int>& nums, int target)
{
    int left=0;
    int right=nums.size()-1;
    while(left <= right)
    {
        int mid=int((left+right)/2);
        if(target==nums[mid])
            return mid;
        else if(target>nums[mid])
            left=mid+1;
        else if(target<nums[mid])
        
            right=mid-1;
    }

            return -1;
 }
                };
```


2.圖片
![](https://i.imgur.com/cYYAyCH.png)
3.花費時間:50分鐘(4)完成程度:GOOLE觀念自己在理解寫程式。
## 3.二元搜尋應用：當數字可以重覆
   1.程式碼
   ``` C++=
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int search(vector<int>& nums, int target)
{

    int left=0;
    int right=nums.size()-1;
    while(left <= right)
    {
        int mid=int((left+right)/2);


        if(target>nums[mid])
            left=mid+1;
        else if(target<=nums[mid])

            right=mid-1;//解題關鍵
    }
    if(nums[left]==target)
    {
        return left;//當N未在數列中則輸出>N的最小index
    }

    return -1;
}
int main() {
    vector<int> nums = {1,3,3,6};
    cout << search(nums, 2) ;
    }
``` 
 2.圖片
 ![](https://i.imgur.com/KiyouAq.png)

![](https://i.imgur.com/C9NZVxc.png)
![](https://i.imgur.com/TXL2hlI.png)
3.花費30分鐘(4)完成程度:跟同學討論，程式部分自己完成
## 4. 二元搜尋應用：找數字該插入的位置
1.程式碼
 ``` C++=
class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
         int left=0;
    int right=nums.size()-1;
    while(left <= right)
    {
        int mid=int((left+right)/2);
        if(target==nums[mid])
            return mid;
        else if(target>nums[mid])
            left=mid+1;
        else if(target<nums[mid])

            right=mid-1;
    }

    return left;
    }
};
 
 ``` 
 2.圖片
 ![](https://i.imgur.com/E5rhsJx.png)

 3.花費時間:1hr
 4.完成狀態:用紙筆找出規律理解
 ## 5. 二元搜尋應用：找到最早出問題的版本

1.程式碼
``` C++=
class Solution {
public:
    int firstBadVersion(int n) 
    {
    int left=1;
    int right=n;
    int mid;
    while(right>left)//等於會無限循環
    {
        mid=left+((right-left)/2); //防止溢位
        if(isBadVersion(mid))
        {
           right=mid; 
            
        }
        else
        {
            left=mid+1;
        }
    }
    return left;        
    }
};
``` 
2.圖片
![](https://i.imgur.com/dOze8jG.png)


3.花費時間:1hr
4.因為一些BUG找不出來發現是溢位的問題，參考第三題
## 6. 二元搜尋應用：開根號後的整數部分

   1.程式碼
   ``` C++=
#include<iostream>
using namespace std;
int intsqrt(int x)
{
    long int left=1;
    long int right=x;
    while(left<=right)
    {
        long int mid=left+(right-left)/2;
        if(mid*mid<x)
        {
            left=mid+1;
        }
        else if(mid*mid>x)
        {
            right=mid-1;
        }
        else
            return (int)mid;
    }
    if(left*left>x)//解決非完全平方數left會停留在>X的平方數
    {
        return(int)(left-1);
    }
    else
        return(int)left;//多餘
}
int main()
{
    int x;
    cin>> x;
    int y;
    y=intsqrt(x);
    cout<<y<<endl;
}

   ``` 
   2.圖片
   ![](https://i.imgur.com/As2U7TX.png)

   3.花費時間:50分鐘
   4.完成狀況:有GOOLE並且已經學會。
   ## 7.心得感想
   這次作業雖然題目的難度都是簡單，但是好像是因為太久沒寫程式了，有一點生疏，花了一整個下午，課程部分都還聽得懂，寫完的確更了解二元搜尋法如何運作跟應用，一開始看到四題星期二要交很緊張，怕來不及，好險這四題都有關聯，因為之前在寫UVA的時候卡題都是可以卡一整天的，我自己本身寫程式方面較弱，很多東西都要比別人學的還來的久，希望下次題目可以提早公布!