練習題

Q11661: Burger Time (漢堡時刻)

題目連結 : http://luckycat.kshs.kh.edu.tw/homework/q11661.htm

[想法]

  • 遇到Z,也就是同時是藥局跟餐廳,那麼最短距離為0,可以直接結束,不用再計算
  • 遇到R或D,把他們記錄下來,所以每次遇到R或D的時候比較是否跟之前紀錄的資料相同,如果不同就代表這是藥局與餐廳之間的距離
  • 如果找到這段距離比上次找到的距離還短,就更新答案

[code]


#include <iostream>
using namespace std;

int main() {
  int L; //資料長度
  char road, state;
  int position;
  int distance; //藥局與餐廳的距離,也就是案答

  while (cin >> L && L != 0) {

    state = '.';
    position = -1;
    distance = 2000001;

    for (int i = 0; i < L; i++) {

      cin >> road;

      //如果有藥局跟餐廳合併的店,距離直接為0
      if (road == 'Z') distance = 0;

      //遇到藥局或是餐廳
      if (road != '.') {
        // 代表R遇到D或是D遇到R
        if (state != road && state != '.') {
          //目前的位置與前一個(R或D)的距離有比目前的最短路徑還短嗎?
          if (i - position < distance) {
            distance = i - position; //將最短距離更新
          }
        }
        state = road; //紀錄最新的藥局或是餐廳
        position = i; //紀錄位置

      }
    }
    cout << distance << endl;
  }
  return 0;
}

Q11369: Shopaholic (購物狂)

[想法]

  • 3樣物品,最便宜的那一樣免費,那絕對是拿最貴的3樣物品先結帳
  • 所以我們要先將價位由大排到小,依序挑出3樣物品中最便宜的那一樣來計算

[code]

#include <iostream> 
#include <algorithm>
using namespace std;

//比較大的數字放前面
bool cmp(int a, int b) {
  return a > b;
}

int main() {
  int num;
  cin >> num; //測資的組數
  while (num--) {

    int i, j, n, save = 0, tmp;
    int p[20000] = {
      0
    };

    cin >> n; //商品數量

    for (i = 0; i < n; i++) {
      cin >> p[i]; //每樣商品的價錢
    }

    sort(p, p + n, cmp);

    //每三個商品一起結帳
    for (i = 2; i < n; i += 3) {
      save += p[i]; //取得三樣商品中最便宜的價錢
    }
    cout << save << endl; //省下錢的總數
  }
  return 0;
}

d418: 00993 - Product of digits

https://zerojudge.tw/ShowProblem?problemid=d418

http://luckycat.kshs.kh.edu.tw/homework/q993.htm

內容 :

給你一個大於等於 0 的整數 N,請你你找到最小的自然數 Q ,使得在 Q 中所有數字(digit)的乘積等於 N 。 例如:N=10, 可以找到Q=25,因為 2*5=10

輸入說明:

輸入的第一列有一個整數代表共有多少組測試資料。 每組測試資料一列有1個整數 N(0 <= N <= 1000000000

輸出說明:

每組測試資料輸出一列,輸出自然數 Q ,如果 Q 不存在,請輸出 -1。

範例輸入:

5 <-代表要輸入5筆測資
1
10
123456789
216
26

範例輸出:

1
25 ← 輸入是10,所以輸出是25,因為 2*5=10
-1 ← 沒有任何數字的每個位數相乘會是 123456789
389
-1

解題提示

題目大意:

給出一個正整數, 要求找到一個自然數,使得該自然數的每一位的數字的乘積等於正整數。並且要求最小,不存在輸出-1.

解題思路:

我們只能2~9這些數字去因式分解N,1因為除下來還是不便,所以可以略過

假如說N=64,能滿足各個位數相乘會是64的自然數有88, 448, 484, 844, 4444等

那該如何取得88呢? 其實就是用最大的因數去除以64就對了,2~9中如果拿8去除的話,得到的因數「個數」會比用4除來的少。

以N=324為例,我們用9~2這些數字來除以,先用9不斷去除以324,每除盡一次就把9存到我們的答案(答案成宣告一個陣列),發現324可以被9除兩次,所以答案終究存了2個9,這時的324被2個9整除後會變成4,接著我們依序用8~5去除以4都沒辦法整除,接著用4除以4,並把4也存到答案裡面,此時的答案目前為{9,9,4},而N也被分解成N=1,這也就代表N已經被除盡,可以不用再拿2跟3來除以N。

{9, 9, 4}可以被拿來組成499 , 949, 994,但我們要的是499,那我們該怎麼做呢?其實就是最小的數字移到陣列最左邊,最大的放最右邊,用sort就可以解決了。

1是比較特殊的情況, 因為終止條件是n == 1和i < 2, 所以一開始就要處理掉1的情況,單獨考慮, 然後當因子全部分解完之後,n 仍然不等1,說明不能完全分解成2 ~9之間的因子,輸出-1.


#include <iostream>
#include <algorithm>
using namespace std;

const int Max = 40;
int num[Max] = {0};//記錄N的所有因數

int main () {

    int n, N, cnt;

    cin>>n;//n比測資

    while (n--) {

        cin>>N;

        cnt = 0; //N是用cnt個個位數字相乘

        if (N != 1) {

            //拿 9~2 來做因式分解,因為N只允許用個位數字當因數
            for (int i = 9; i > 1; i--) {

                while (N % i == 0) {
                    num[cnt++] = i;
                    N = N / i;
                }

                //N已被分解完成,提早跳出
                if (N == 1) break;

            }

            //陣列是由大到小,所以要轉成由小到大
            sort(num, num + cnt);

            if (N != 1){
                //找不到
                cout<<"-1"<<endl;
            }
            else {
                //找到了
                for (int i = 0; i < cnt; i++)
                   cout<<num[i];
                cout<<endl;
            }
        }
        else{
            //如果N=1的話,特例處理
            cout<<"1"<<endl;
        }

    }
    return 0;
}

其他練習

results matching ""

    No results matching ""