顯示具有 APCS 標籤的文章。 顯示所有文章
顯示具有 APCS 標籤的文章。 顯示所有文章

TOJ 110 六芒星的咒符參考解法

若您覺得文章寫得不錯,請點選文章上的廣告,來支持小編,謝謝。

If you like this post, please click the ads on the blog or buy me a coffee. Thank you very much.

原始題目連結:TOJ 110 六芒星的咒符

此題要用 * 符號劃出六芒星,六芒星是由一個正三角形和一個倒三角形所組成的,中間有三行重疊,圖案如下圖


參考解法
因為此六芒星圖形是上下兩半對稱的,若以高度 height = 4 為例,可以將垂直軸轉換成 -k/2 到 k/2 值(下圖的 line 變數),而 k 值為六芒星行數。此時可以算出空白個數與星星個數(spaceAndStar)的總數為 2*height - 1,而空白數就是 line 變數的絕對值再加1,星星數為spaceAndStar - 2 * space。




用 height = 5 與 height = 6 來測試一下



以上的數學推導似乎可行,來寫程式吧。

C++程式碼:




結果





高中生程式解題系統:d485: 我愛偶數

 若您覺得文章寫得不錯,請點選文章上的廣告,來支持小編,謝謝。

If you like this post, please click the ads on the blog or buy me a coffee. Thank you very much.

題目連結 https://zerojudge.tw/ShowProblem?problemid=d485

題目說明文文很喜歡偶數,他甚至有收集偶數的習慣。你給他一個範圍的連續整數,他就會把其中的偶數留下來收藏。如今他又拿到了一個範圍的整數,請問他這次收藏了幾個偶數?對文文來說,0 也算是一個偶數哦!

輸入
輸入只有一行,其中含有兩個由空白隔開的整數 a, b (0 ≤ a ≤ b ≤ 2147483647)。

輸出
輸出一個整數,代表 a 與 b 之間 (含 a 與 b) 一共有多少個偶數。


解題說明
解題方法一:暴力法(效率不好)
用一個變數even來記錄有幾個偶數。
使用迴圈對a與b之間的數做是不是偶數判斷。

C++ 程式碼
  1. #include<iostream>
  2. using namespace std;
  3.  
  4. int main(void) {
  5.   int a, b, even = 0;
  6.   cin >> a >> b;
  7.  
  8.   for(int i = a; i <= b; i++)
  9.     if( (& 1) == 0) even++;
  10.  
  11.   cout << even << endl;
  12. }

解題方法二:數學分析法
a與b有四種狀況
1. a 為奇數,b 為奇數
例如 a = 1,b = 3 時,偶數總共有 (b - a) / 2 = (3 - 1)/2 = 1。

2. a 為奇數,b 為偶數
例如 a = 1,b = 4 時,偶數總共有 (b - a) / 2 + 1 = (4 - 1)/2 + 1 = 1 + 1 = 2。

3. a 為數,b 為奇數
例如 a = 0,b = 7 時,偶數總共有 (b - a) / 2  + 1 = (7 - 0)/2 + 1 = 3 + 1 = 4。

4. a 為數,b 
例如 a = 0,b = 8 時,偶數總共有 (b - a) / 2  + 1 = (8 - 0)/2 + 1 = 4 + 1 = 5。

可將任意整數用位元運算AND( & ) 與數字 1 做運算。
n是奇數,則 n & 1 結果為 1。
n是偶數,則 n & 1 結果為 0。

因此a 為奇數,b 為奇數時,可以用 (b - (b&1) - a - (a&1)) / 2 + 1 來算出有幾個偶數。此式子在其他a與b三種狀況也適用。

C++ 程式碼
  1. #include<iostream>
  2. using namespace std;
  3.  
  4. int main(void) {
  5.   int a, b;
  6.   cin >> a >> b;
  7.   int cnt = (- (b&1) - a - (a&1)) / 2 + 1;
  8.   cout << cnt << endl;
  9. }

程式語言實作練習題 2022.08.13

若您覺得文章寫得不錯,請點選文章上的廣告,來支持小編,謝謝。

If you like this post, please click the ads on the blog or buy me a coffee. Thank you very much.

第一題:a038: 數字翻轉

a038. 數字翻轉- 高中生程式解題系統

這題常見的解法會類似如下:


也可以用字串來解:




C++程式碼:

  1. #include <iostream>
  2. #include <sstream>
  3.  
  4. using namespace std;
  5.  
  6. int main()
  7. {
  8.     string s;
  9.     while(cin >> s)
  10.     {
  11.         short len = s.length();
  12.         bool hasZero = true;
  13.  
  14.         for(short i = len - 1; i >= 0; i--)
  15.         {
  16.             if( s[i] != '0' )   hasZero = false;
  17.             if( !hasZero )  cout << s[i];
  18.         }
  19.         cout << endl;
  20.     }
  21.     return 0;
  22. }
  23.  
  24.  
  25.  
用Python 程式語言來解,短短幾行就解決了!這是因為 python 有Slicing語法可用。

Python程式碼:

1
2
3
4
import sys

for s in sys.stdin: # 輸入數字
    print(int(s[::-1])) # 反轉

第二題:a291: nAnB problem

a291. nAnB problem - 高中生程式解題系統

首先需要了解此題的規則,例如測試資料為

8 4 7 5
4
1 2 3 4
8 1 2 4
4 7 5 8
8 4 7 5

輸出結果會是
1234 ==> 0A1B
8124 ==> 1A1B
4758 ==> 0A4B
8475 ==> 4A0B

了解以上的規則後,就可以用比對的方式計算出有多少個 A與多少個 B了。
可用一層迴圈算出幾個 A。
可用兩層迴圈算出幾個 B。


C++ 程式碼:

  1. #include <cstdio>
  2. #include <iostream>
  3.  
  4. using namespace std;
  5.  
  6. int main() {
  7.     int CNT = 4;
  8.  int answer[CNT];
  9.  int guess[CNT];
  10.  int idx = 0;
  11.     int round = 0;
  12.  
  13.  while( scanf("%d %d %d %d"&answer[0]&answer[1]&answer[2]&answer[3])!=EOF ) {
  14.         scanf("%d"&round);
  15.  
  16.         int a[round] = { 0 };
  17.         int b[round] = { 0 };
  18.  
  19.         idx = 0;
  20.         while( idx < round ) {
  21.             int guessIdx = 0;
  22.             int found[CNT] = { 0 };
  23.  
  24.             while( guessIdx < CNT ) {
  25.                 scanf("%d"&guess[guessIdx]);
  26.  
  27.                 // How many A.
  28.                 if(guess[guessIdx] == answer[guessIdx]) {
  29.                     a[idx]++;
  30.                     found[guessIdx] = 1;
  31.                 } else {
  32.                     found[guessIdx] = 0;
  33.                 }
  34.  
  35.                 guessIdx++;
  36.             }
  37.  
  38.             // How Many B.
  39.             for( guessIdx = 0; guessIdx < CNT; guessIdx++) {
  40.                 if( found[guessIdx] != 1 )
  41.                 for(int answerIdx = 0; answerIdx < CNT; answerIdx++) {
  42.                     if( found[answerIdx] == 0 && (guess[guessIdx] == answer[answerIdx]) && guessIdx != answerIdx ) {
  43.                         b[idx]++;
  44.                         found[answerIdx] = 2;
  45.                         break;
  46.                     }
  47.                 }
  48.             }
  49.  
  50.             idx++;
  51.         }
  52.  
  53.         idx = 0;
  54.         while( idx < round ) {
  55.             printf("%dA%dB\n", a[idx], b[idx]);
  56.             idx++;
  57.         }
  58.  }
  59.  return 0;
  60. }


APCS實作題2022年6月第1題數字遊戲參考解法

若您覺得文章寫得不錯,請點選文章上的廣告,來支持小編,謝謝。

If you like this post, please click the ads on the blog or buy me a coffee. Thank you very much.

題目連結 https://zerojudge.tw/ShowProblem?problemid=i399

題目說明
給三個介於 1 ~ 9 的整數 A1,A2,A3。
先輸出一個正整數 P 表示眾數數量,也就是出現最多次的數字的次數。
接下來將輸入的三個數字去除重複(剩下一個)後由大到小依序輸出。

範例一:
輸入 6 6 6 ,輸出 3 6。
因為出現最多次的數字是 6,共出現 3 次,並且只有出現 6 這個數字,因此輸出 3 6。

範例二:
輸入 7 9 7 ,輸出 2 9 7。
因為出現最多次的數字是 7,共出現 2 次,並且出現了 7 和 9,因為集合需要由大到小輸出,因此輸出 2 9 7。

範例三:
輸入 4 1 8 ,輸出 1 8 4 2。
因為三個數字各出現 1 次,集合由大到小輸出,因此輸出 1 8 4 1。

想法:
  1. 將輸入的數字記錄在陣列A。
  2. 用陣列或串列cnt紀錄數字 1 ~ 9 各自出現幾次。找次數陣列cnt中的次數最大值。
  3. 依次數值對陣列A由小排到大。
  4. 對陣列A,從最大值開始輸出不重複的數字,

C++ 程式碼
#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
  const int N = 3;
  int a[N];

  while(cin >> a[0] >> a[1] >> a[2]) {
    int cnt[10] = {0};  // 紀錄數字 1 ~ 9 各自出現幾次
    // 算數字 1 ~ 9 各自出現幾次
    for(int i = 0; i < N; i++)
      cnt[a[i]]++;
    // 找眾數數量P
    int P = 0;
    for(int i = 0; i < 10; i++)
      if(P < cnt[i]) P = cnt[i];
   
    cout << P << " ";
    sort(a, a + N);   // 由小排到大
    cout << a[2];     // 從最大數字輸出

    for(int i = 1; i >= 0; i--)
      if(a[i+1] != a[i]) // 輸出不重複的數字
        cout << " " << a[i];

    cout << endl;
  }
  return 0;
}


Python 程式碼
while True:
    try:
        A = list(map(int, input().split()))
        # 紀錄數字 1 ~ 9 各自出現幾次
        cnt = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        # 算數字 1 ~ 9 各自出現幾次
        for a in A:
            cnt[a] = cnt[a] + 1
        # 找眾數數量P
        P = max(cnt)
        print(P, end = " ")
        A.sort() #  由小排到大
        print(A[2], end = "") # 從最大數字輸出

        for idx in range(1, -1, -1):
            if A[idx+1] != A[idx]: # 輸出不重複的數字
                print(" " + str(A[idx]), end="")        
        print()
    except EOFError:
        break


高中生程式解題系統:e621: 1. 免費停車 (Free Parking)

若您覺得文章寫得不錯,請點選文章上的廣告,來支持小編,謝謝。

If you like this post, please click the ads on the blog or buy me a coffee. Thank you very much.

題目連結 https://zerojudge.tw/ShowProblem?problemid=e621

想法:
  1. 用一個變數 hasFree 來記錄是否有免費停車位。
  2. 用迴圈來處理 大於A、小於B。
  3. 用取餘數運算子 % 與 if 來判斷是否被 C 整除。

C++ 參考程式碼
#include <iostream>
using namespace std;

int main()
{
  int N; // 幾天放送優惠
  cin >> N;
  int a, b, c;

  while(N--) {
    cin >> a >> b >> c;
    bool hasFree = false; // 是否有免費停車位
 
    for(int idx = a + 1; idx < b; idx++) { // 大於a、小於b
      if( idx % c != 0) { // 不被 c 整除
        if(hasFree) cout << " ";  // 因為已有免費車位,先輸出空白來區隔
        hasFree = true;           // 有免費車位
        cout << idx;              // 輸出車位號碼
      }
    }

    if(hasFree == false)  // 無免費車位
      cout << "No free parking spaces.";

    cout << '\n';
  }
}


Python 參考程式碼
N = int(input()) # 幾天放送優惠

while(N):
    data = input()
    hasFree = False # 是否有免費停車位
    a, b, c = list(map(int, data.split(' ')))

    for idx in range(a+1, b): # 大於a、小於b
        if( idx % c != 0 ): # 不被 c 整除
            if hasFree:
                print(end= ' ') # 因為已有免費車位,先輸出空白來區隔
            print(idx, end = "") # 輸出車位號碼
            hasFree = True # 有免費車位
   
    if(hasFree == False): # 無免費車位
        print("No free parking spaces.", end = "")
    print()
    N = N - 1


C語言練習題:指標(C language exercise: Pointer)

若您覺得文章寫得不錯,請點選文章上的廣告,來支持小編,謝謝。

If you like this post, please click the ads on the blog or buy me a coffee. Thank you very much.

Pointer concepts:
2. Introduction to C Pointers

練習一:基本語法
設計一個C語言程式來呈現指標的語法,例如宣告、取址、取值等。

Exercise 1: Basic Syntax
Design a C program to demonstrate the basic syntax of pointer. Such as declaration, address and value. 

練習一參考解法:
Exercise 1 solution:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
Pointer Basic Syntax
Author: Holan
*/

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int n = 50;

    // declaration
    int *ip;

    // assignment
    ip = &n;

    printf("The value of &n:%X\n", &n);
    printf("The value of n:%i\n", n);

    printf("The value of &ip:%X\n", &ip);
    printf("The value of ip:%X\n", ip);
    printf("The value of *ip:%i\n", *ip);
    return 0;
}


練習二:動態記憶體配置
撰寫用 malloc()free() 來配置記憶體的程式。

Exercise 2: Dynamic Memory Allocation
Write a C program to allocate memory.

練習二參考解法:
Exercise 2 solution:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
Dynamic memory allocation
Author: Holan
*/

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int n;
    int *pI;

    printf("How many integers? ");
    scanf("%d", &n);

    // using malloc to allocate memory
    pI = (int *) malloc(n*sizeof(int));

    if(pI == NULL) // if fail to allocate
    {
        printf("Couldn't allocate memory\n");
        return 0;   // exit
    }

    // Releasing the memory allocated by malloc
    free(pI);

    return 0;
}


練習三:兩數相乘
使用指標的方式,將兩個數字相乘。

Exercise 3: Multiplying two numbers
Multiplying two numbers with pointers.

練習三參考解法:
Exercise 3 solution:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
Multiplying two numbers with pointers
Author: Holan
*/

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int n1, n2;
    int *pn1, *pn2, product;

    printf("Enter num1:");
    scanf("%d", &n1);

    printf("Enter num2:");
    scanf("%d", &n2);

    pn1 = &n1;
    pn2 = &n2;

    product = *pn1 * *pn2;

    printf("The product of %d and %d is %d\n", *pn1, *pn2, product);
    return 0;
}

練習四:指標與陣列
使用指標的語法來取得整數陣列的元素。

Exercise 4: Pointer and array
Using a pointer to access the elements of an integer array.

練習四參考解法:
Exercise 4 solution:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
/*
Pointer and array
Author: Holan
*/

#include <stdio.h>
#include <stdlib.h>

#define N 5
int main()
{
    int a[N] = { 2, 3, 5, 7, 11};
    int *pI = a;

    for(int i = 0; i < N; i++)
        printf("a[%d] = %d\t", i, *(pI + i));
    return 0;
}

練習五:指標運算
在練習四時,使用到指標與整數相加的運算。而本題請使用遞增與遞減來達成與練習四一樣的功能。

Exercise 5: Pointer Arithmetic
In exercise 4, the operation: "a pointer plus a integer" is used. Could we use pointer increment and decrement to do exercise 4?

這篇連結文章可以幫助瞭解指標運算
Here is a tutorial: "How pointer arithmetic works?"

練習五參考解法:
Exercise 5 solution:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
Pointer Arithmetic: increment and decrement
Author: Holan
*/

#include <stdio.h>
#include <stdlib.h>

#define N 5
int main()
{
    int a[N] = { 2, 3, 5, 7, 11};
    int *pI = a;

    printf("Pointer increment:");
    // pointer increment
    for(int i = 0; i < N; i++)
        printf("a[%d] = %d\t", i, *(pI++));


    printf("\n\nPointer decrement:");
    // pointer decrement
    for(int i = N - 1; i >= 0; i--)
        printf("a[%d] = %d\t", i, *(--pI));

    return 0;
}

練習六:字串長度
使用指標語法來求出所輸入字串的長度。

Exercise 6: The length of a string
Using pointer to calculate the length of a user input string.

練習六參考解法:
Exercise 6 solution:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
Length of a string
Author: Holan
*/

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char str[100];
    int len = 0;

    printf("Enter a string:");

    // Input a string with whitespaces
    scanf("%[^\n]s", str);

    char *pC = str;

    while(*pC != '\0')
    {
        len++;
        pC++;
    }

    printf("The length of the given string[%s] is:%d", str, len);

    return 0;
}


練習七:交換兩數
使用 call by reference 的方式,設計一個可以交換兩數的函式。

Exercise 7: Swap two numbers
Using call by reference to design a function that swaps two numbers.

練習七參考解法:
Exercise 7 solution:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/*
Swap two numbers
Author: Holan
*/

#include <stdio.h>
#include <stdlib.h>

void swapV(double *x, double *y);

int main()
{
    double n1, n2;

    printf("Enter number 1:");
    scanf("%lf", &n1);

    printf("Enter number 2:");
    scanf("%lf", &n2);

    printf("Before swap n1:%lf, n2:%lf", n1, n2);
    swapV(&n1, &n2);
    printf("\nAfter swap n1:%f, n2:%f", n1, n2);

    return 0;
}

void swapV(double *x, double *y)
{
    double t = *x;
    *x = *y;
    *y = t;
}

練習八:字串合併
使用指標語法來合併兩字串。

Exercise 8: String concatenation
Using pointer to concatenate two strings.

練習八參考解法:
Exercise 8 solution:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/*
String concatenation
Author: Holan
*/

#include <stdio.h>
#include <stdlib.h>

#define LEN 256
int main()
{
    char str1[LEN];
    char str2[LEN];
    char str3[LEN*2];

    printf("Enter str1:");
    scanf("%[^\n]%*c", str1);

    printf("Enter str2:");
    scanf("%[^\n]%*c", str2);

    char *pC = str1;
    char *pStr = str3;

    while(*pC)
    {
        *pStr = *pC;
        pC++;
        pStr++;
    }

    pC = str2;
    while(*pC)
    {
        *pStr = *pC;
        pC++;
        pStr++;
    }

    // end with '\0'
    *pStr = '\0';
    printf("Str1:%s, Str2:%s, Str3:%s", str1, str2, str3);

    return 0;
}

練習九:空指標
常見的觀念可參考「空指標與NULL」。
請撰寫一程式來練習空指標的語法。

Exercise 9: null pointer 
Please refer to this tutorial: NULL pointer in C.
Design a C program to practice the null pointer syntax.

練習九參考解法:
Exercise 9 solution:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*
NULL pointer
Author: Holan
*/

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int *iP = NULL;

    if(iP == NULL)
    {
        printf("The value of iP is %u", iP);

        // Couldn't access to *iP
        // The following code will crush
        printf("The value of *iP is %d", *iP);
    }
    else
    {
        printf("The value of iP is %u", iP);
        printf("The value of *iP is %d", *iP);
    }

    return 0;
}

練習十:函式指標
可參考此篇文章:[C語言] function pointer介紹來了解 function pointer。
請設計一程式來練習 function pointer,例如兩數字的加、減、乘、除等運算。

Exercise 10: Function Pointer
Please refer to this tutorial: Function pointers in C.
Design a C program to practice function pointer. For example, addition, subtraction, multiplication and division of two numbers. 

練習十參考解法:
Exercise 10 solution:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*
Function pointers
Author: Holan
*/

#include <stdio.h>
#include <stdlib.h>

double add(double n1, double n2);
double sub(double n1, double n2);
double mul(double n1, double n2);
double divi(double n1, double n2);

int main()
{
    double a = 3.44, b = 9.999;

    double (*op)(double, double) = add;

    printf("The addition of %f and %f is %f\n", a, b, op(a, b));

    op = sub;
    printf("The subtraction of %f and %f is %f\n", a, b, op(a, b));

    op = mul;
    printf("The multiplication of %f and %f is %f\n", a, b, op(a, b));

    op = divi;
    printf("The division of %f and %f is %f\n", a, b, op(a, b));

    return 0;
}

double add(double a, double b) { return a + b;}
double sub(double a, double b) { return a - b;}
double mul(double a, double b) { return a * b;}
double divi(double a, double b) { return a / b;}