---
# System prepended metadata

title: '**演算法作業 HW1**'

---

# **演算法作業 HW1**
<font size=5>**1. 本週影片中提到的NP-complete問題有哪些？**</font>
---
* Knapsack problem
* Traveling salesperson problem
* Partition problem
* Art gallery problem

<font size=5>**2. 請上網找一個老師沒說過的NP-complete問題，並舉個例子說明該問題的輸入與輸出。**</font>
---
圖著色問題(Graph Coloring Problem)
* 定義：給定一個無向圖 **G = ( V , E )**，其中 **V** 為頂點集合，**E** 為邊集合，圖著色問題即為將 **V** 分為 **K** 個顏色組，每個組形成一個獨立集，即其中沒有相鄰的頂點。優化版本是希望獲得最小的 **K** 值。
* 舉例：
下圖是一個無向圖，用 **K** 個顏色將所有頂點上色，且相鄰點顏色不可相同，求最小值 **K** 。
![](https://i.imgur.com/sCmyULD.png)
經過計算，可以得出下圖其中一種可能，最小值 **K** 為 3。
![](https://i.imgur.com/NnAPFFO.png)

<font size=5>**3. 二元搜尋應用：當數字可以重覆**</font>
---
數字可能重複，回傳找到最小index。
只要找到後不停止，繼續往左區間找就好了。
完全靠自己，花費時間：1分鐘。
```c++
#include<iostream>
#include<vector>
#include<sstream>
using namespace std;
//數字重複，回傳找到最小index
int binary_search(vector<int>nums,int target)
{
    int l=0,r=nums.size()-1,mid,ans=-1;
    while(l<=r)
    {
        mid=(l+r)/2;
        if(nums[mid]==target)//找到跟target相同的數
        {
            ans=mid;
            r=mid-1;//即使找到也繼續往左區間尋找
        }
        else if(nums[mid]>target)
        {
            r=mid-1;
        }
        else
        {
            l=mid+1;
        }
    }
    return ans;
}
int main()
{
    vector<int>nums;
    string s;
    int num,t;
    
    cout<<"輸入數列：";
    getline(cin,s);
    stringstream s1;
    s1<<s;
    while(s1>>num)
    {
        nums.push_back(num);
    }
        
    cout<<"輸入要尋找的數：";
    cin>>t;
    
    cout<<binary_search(nums,t)<<endl;
    
    return 0;
}
```
執行結果：
![](https://i.imgur.com/Y2JQNSg.png)
![](https://i.imgur.com/w50RZii.png)
![](https://i.imgur.com/dyfTlOV.png)


<font size=5>**4. 二元搜尋應用：找數字該插入的位置**</font>
---
[35. Search Insert Position - LeetCode](https://leetcode.com/problems/search-insert-position/)
若找不到數字則回傳應該插入的位置。
如果while迴圈跑到最後還是找不到，直接回傳左邊界的index即可。
完全靠自己，花費時間：一分鐘。
```c++
class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int l=0,r=nums.size()-1,mid;
        while(l<=r)
        {
            mid=(l+r)/2;
            if(nums[mid]==target)
            {
                return mid;
            }
            else if(nums[mid]>target)
            {
                r=mid-1;
            }
            else
            {
                l=mid+1;
            }
        }
        return l;
    }
};
```
![](https://i.imgur.com/65PDEyQ.png)

<font size=5>**5. 二元搜尋應用：找到最早出問題的版本**</font>
---
[278. First Bad Version - LeetCode](https://leetcode.com/problems/first-bad-version/)
這題只是第三題的變體而已，同樣是找到後繼續往左區間找。
要注意的是用int會爆。
完全靠自己，花費時間：一分鐘。
```c++
// The API isBadVersion is defined for you.
// bool isBadVersion(int version);

class Solution {
public:
    int firstBadVersion(int n) {
        long l=1,mid,ans;
        while(l<=n)
        {
            mid=(l+n)/2;
            if(isBadVersion(mid))
            {
                ans=mid;
                n=mid-1;
            }
            else
            {
                l=mid+1;
            }
        }
        return ans;
    }
};
```
![](https://i.imgur.com/CzZeSZg.png)

<font size=5>**6. 二元搜尋應用：開根號後的整數部分**</font>
---
[69. Sqrt(x) - LeetCode](https://leetcode.com/problems/sqrtx/)
把x當右邊界r用二分搜下去找，找不到就回傳r。
一樣要注意用int會爆。
完全靠自己，完成時間：一分鐘。
```c++
class Solution {
public:
    int mySqrt(int x) {
        long l=1,r=x,mid;
        while(l<=r)
        {
            mid=(l+r)/2;
            if(mid*mid==x)
            {
                return mid;
            }
            else if(mid*mid>x)
            {
                r=mid-1;
            }
            else
            {
                l=mid+1;
            }
        }
        return r;
    }
};
```
![](https://i.imgur.com/t8aM0x1.png)

<font size=5>**7. 本週心得**</font>
---
有些題目因為做過了所以做蠻快的，還可以跟上，影片方面也沒什麼問題。

---
若有錯誤歡迎指正
