[0]zero-index clytie0x/zero-index

3.5 แบบฝึกหัด

เขียนแต่ละข้อเป็นไฟล์ใหม่ใน Code::Blocks รันแล้วเทียบกับผลลัพธ์ที่ต้องได้ให้ตรงทุกตัวอักษร รวมถึงช่องว่างและการขึ้นบรรทัด ติดจริงๆ ค่อยเปิดคำใบ้ และเปิดเฉลยหลังทำเสร็จแล้วเท่านั้น

ข้อ 1 ผ่านหรือไม่ผ่าน

ระดับง่าย เวลาไม่เกิน 1 วินาที

วิชาคอมพิวเตอร์มีคะแนนเก็บเต็ม 40 คะแนน และคะแนนสอบปลายภาคเต็ม 60 คะแนน นักเรียนจะผ่านวิชานี้เมื่อคะแนนรวมทั้งสองส่วนได้ตั้งแต่ 50 คะแนนขึ้นไป ให้บอกว่านักเรียนคนหนึ่งผ่านหรือไม่

ข้อมูลเข้า

บรรทัดเดียว มีจำนวนเต็ม A คือคะแนนเก็บ และ B คือคะแนนสอบปลายภาค คั่นด้วยช่องว่าง โดยที่ 0 ≤ A ≤ 40 และ 0 ≤ B ≤ 60

ข้อมูลออก

พิมพ์ pass ถ้าผ่าน หรือ fail ถ้าไม่ผ่าน

32 25
pass
20 29
fail
ดูคำใบ้

บวกคะแนนสองส่วนก่อน แล้วเทียบผลรวมกับ 50 ด้วย if else ระวังคะแนนรวม 50 พอดีต้องได้ pass จึงต้องใช้ >= ไม่ใช่ >

ดูเฉลย
#include <stdio.h>

int main()
{
    int collected, exam;
    scanf("%d %d", &collected, &exam);
    if (collected + exam >= 50) {
        printf("pass\n");
    } else {
        printf("fail\n");
    }
    return 0;
}

ข้อ 2 ใครเข้าเส้นชัยก่อน

ระดับง่าย เวลาไม่เกิน 1 วินาที

การแข่งวิ่ง 100 เมตรรอบชิงมีนักวิ่งสองคน คนแรกใช้เวลา A หน่วย คนที่สองใช้เวลา B หน่วย หนึ่งหน่วยคือหนึ่งในร้อยวินาที ใครใช้เวลาน้อยกว่าคือผู้ชนะ ให้บอกว่าใครชนะ

ข้อมูลเข้า

บรรทัดเดียว มีจำนวนเต็ม A และ B คั่นด้วยช่องว่าง โดยที่ 1 ≤ A, B ≤ 100000

ข้อมูลออก

พิมพ์ first ถ้าคนแรกชนะ พิมพ์ second ถ้าคนที่สองชนะ หรือพิมพ์ tie ถ้าใช้เวลาเท่ากัน

1253 1187
second
1000 1000
tie
ดูคำใบ้

เวลาน้อยกว่าคือวิ่งเร็วกว่า ไม่ใช่เวลามากกว่า ใช้ if ตามด้วย else if แล้วปิดด้วย else ให้ครบสามกรณี อย่าลืมกรณีที่เวลาเท่ากัน

ดูเฉลย
#include <stdio.h>

int main()
{
    int first_time, second_time;
    scanf("%d %d", &first_time, &second_time);
    if (first_time < second_time) {
        printf("first\n");
    } else if (second_time < first_time) {
        printf("second\n");
    } else {
        printf("tie\n");
    }
    return 0;
}

ข้อ 3 ค่าเข้าสวนสัตว์

ระดับง่าย เวลาไม่เกิน 1 วินาที

สวนสัตว์แห่งหนึ่งคิดค่าเข้าตามอายุ ดังนี้

อายุค่าเข้า
ต่ำกว่า 3 ปีไม่เสียเงิน
3 ถึง 12 ปี60 บาท
13 ถึง 59 ปี120 บาท
60 ปีขึ้นไป60 บาท

ให้หาค่าเข้าของผู้เข้าชมหนึ่งคน

ข้อมูลเข้า

บรรทัดเดียว มีจำนวนเต็ม A คืออายุเป็นปี โดยที่ 0 ≤ A ≤ 120

ข้อมูลออก

ค่าเข้าเป็นบาท ถ้าไม่เสียเงินให้พิมพ์ 0

8
60
35
120
ดูคำใบ้

เรียงเงื่อนไขตามอายุจากน้อยไปมาก แล้วต่อกันด้วย else if แต่ละข้อเขียนแค่ขอบบน เช่น age < 3 แล้วตามด้วย age <= 12 เพราะขอบล่างถูกข้อก่อนหน้ากันไว้แล้ว ทดสอบด้วยอายุตรงขอบทุกช่วง คือ 2 3 12 13 59 60

ดูเฉลย
#include <stdio.h>

int main()
{
    int age;
    scanf("%d", &age);
    if (age < 3) {
        printf("0\n");
    } else if (age <= 12) {
        printf("60\n");
    } else if (age <= 59) {
        printf("120\n");
    } else {
        printf("60\n");
    }
    return 0;
}

ข้อ 4 ค่าส่งพัสดุ

ระดับง่าย เวลาไม่เกิน 1 วินาที

บริษัทขนส่งคิดค่าส่งพัสดุตามพื้นที่ปลายทางและน้ำหนัก ดังตาราง

น้ำหนักในจังหวัดต่างจังหวัด
ไม่เกิน 1000 กรัม30 บาท45 บาท
1001 ถึง 5000 กรัม50 บาท70 บาท
เกิน 5000 กรัม80 บาท110 บาท

ให้หาค่าส่งของพัสดุหนึ่งกล่อง

ข้อมูลเข้า

บรรทัดเดียว มีจำนวนเต็ม Z และ W คั่นด้วยช่องว่าง Z คือพื้นที่ปลายทาง เป็น 1 ถ้าส่งในจังหวัด หรือ 2 ถ้าส่งต่างจังหวัด W คือน้ำหนักเป็นกรัม โดยที่ 1 ≤ W ≤ 20000

ข้อมูลออก

ค่าส่งเป็นบาท

1 750
30
2 3200
70
ดูคำใบ้

ใช้ if ซ้อน ชั้นนอกแยกตามพื้นที่ปลายทาง ชั้นในแยกตามน้ำหนักด้วย else if ระวังน้ำหนัก 1000 กับ 5000 กรัมพอดี ยังอยู่ในช่วงที่ราคาถูกกว่า

ดูเฉลย
#include <stdio.h>

int main()
{
    int zone, weight;
    scanf("%d %d", &zone, &weight);
    int price;
    if (zone == 1) {
        if (weight <= 1000) {
            price = 30;
        } else if (weight <= 5000) {
            price = 50;
        } else {
            price = 80;
        }
    } else {
        if (weight <= 1000) {
            price = 45;
        } else if (weight <= 5000) {
            price = 70;
        } else {
            price = 110;
        }
    }
    printf("%d\n", price);
    return 0;
}

ข้อ 5 คะแนนกลางของกรรมการ

ระดับกลาง เวลาไม่เกิน 1 วินาที

การประกวดร้องเพลงมีกรรมการสามคน แต่ละคนให้คะแนนผู้เข้าประกวดเต็ม 100 เพื่อกันกรรมการที่ให้คะแนนสูงหรือต่ำเกินไป จึงตัดคะแนนสูงสุดหนึ่งค่าและต่ำสุดหนึ่งค่าทิ้ง แล้วใช้คะแนนที่เหลือเป็นคะแนนจริง ให้หาคะแนนจริงของผู้เข้าประกวดหนึ่งคน

ถ้ามีคะแนนซ้ำกัน ให้ตัดทิ้งแค่ค่าเดียว เช่น คะแนน 70 70 50 ตัด 70 หนึ่งค่ากับ 50 ทิ้ง เหลือ 70

ข้อมูลเข้า

บรรทัดเดียว มีจำนวนเต็ม A B C คือคะแนนจากกรรมการทั้งสามคน คั่นด้วยช่องว่าง โดยที่ 0 ≤ A, B, C ≤ 100

ข้อมูลออก

คะแนนจริง

72 95 88
88
70 70 50
70
ดูคำใบ้

หาค่ามากสุดด้วยวิธีตั้งแชมป์ในหน้า 3.2 แล้วหาค่าน้อยสุดด้วยวิธีเดียวกัน คะแนนที่เหลือคือผลรวมทั้งสามลบค่ามากสุดและค่าน้อยสุด วิธีนี้ถูกแม้มีคะแนนซ้ำกัน ลองกับ 7 7 3 และ 3 7 7 ดู

ดูเฉลย
#include <stdio.h>

int main()
{
    int a, b, c;
    scanf("%d %d %d", &a, &b, &c);
    int largest = a;
    if (b > largest) {
        largest = b;
    }
    if (c > largest) {
        largest = c;
    }
    int smallest = a;
    if (b < smallest) {
        smallest = b;
    }
    if (c < smallest) {
        smallest = c;
    }
    printf("%d\n", a + b + c - largest - smallest);
    return 0;
}

ข้อ 6 จำนวนวันในเดือน

ระดับกลาง เวลาไม่เกิน 1 วินาที

ให้บอกว่าเดือน M ของปี Y มีกี่วัน เดือนเมษายน มิถุนายน กันยายน และพฤศจิกายนมี 30 วัน เดือนกุมภาพันธ์มี 29 วันในปีอธิกสุรทิน และ 28 วันในปีอื่น เดือนที่เหลือมี 31 วัน

ปี Y เป็นคริสต์ศักราช และใช้กฎปีอธิกสุรทินแบบปฏิทินสากลกับทุกปี คือปีที่หารด้วย 4 ลงตัวแต่หารด้วย 100 ไม่ลงตัว หรือปีที่หารด้วย 400 ลงตัว

ข้อมูลเข้า

บรรทัดเดียว มีจำนวนเต็ม M และ Y คั่นด้วยช่องว่าง โดยที่ 1 ≤ M ≤ 12 และ 1 ≤ Y ≤ 9999

ข้อมูลออก

จำนวนวันในเดือนนั้น

4 2025
30
2 2024
29
ดูคำใบ้

ใช้ switch กับเลขเดือน วาง case ของเดือนที่มี 30 วันติดกันแบบโปรแกรมไตรมาสในหน้า 3.4 เดือนที่เหลือนอกจากกุมภาพันธ์มี 31 วัน ส่วนกุมภาพันธ์ใช้เงื่อนไขปีอธิกสุรทินจากหน้า 3.3 ทดสอบกับปี 1900 และ 2000 ด้วย

ดูเฉลย
#include <stdio.h>

int main()
{
    int month, year;
    scanf("%d %d", &month, &year);
    int days;
    switch (month) {
        case 2:
            if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
                days = 29;
            } else {
                days = 28;
            }
            break;
        case 4:
        case 6:
        case 9:
        case 11:
            days = 30;
            break;
        default:
            days = 31;
    }
    printf("%d\n", days);
    return 0;
}

ข้อ 7 เครื่องคิดเลข

ระดับกลาง เวลาไม่เกิน 1 วินาที

เขียนเครื่องคิดเลขที่รับโจทย์ในรูป A op B แล้วพิมพ์ผลลัพธ์ op เป็นเครื่องหมายหนึ่งในห้าตัวนี้

opผลลัพธ์
+A บวก B
-A ลบ B
*A คูณ B
/A หาร B แบบปัดเศษทิ้ง เหมือน / ของจำนวนเต็มในภาษา C
%เศษจากการหาร A ด้วย B

ถ้า op เป็น / หรือ % แล้ว B เป็น 0 ให้พิมพ์ error แทน

ข้อมูลเข้า

บรรทัดเดียว มีจำนวนเต็ม A ตามด้วยเครื่องหมาย op และจำนวนเต็ม B คั่นกันด้วยช่องว่าง โดยที่ 0 ≤ A, B ≤ 1000000000

ข้อมูลออก

ผลลัพธ์ของการคำนวณ หรือ error

7 / 2
3
15 % 0
error
ดูคำใบ้

รับด้วย scanf("%lld %c %lld", ...) แล้วใช้ switch กับเครื่องหมาย ใน case '/' กับ case '%' ต้องตรวจก่อนว่า B เป็น 0 ไหม ถ้าหารด้วย 0 โปรแกรมจะพังตามหน้า 1.2 ผลคูณใหญ่ถึง 1018 จึงต้องใช้ long long

ดูเฉลย
#include <stdio.h>

int main()
{
    long long a, b;
    char op;
    scanf("%lld %c %lld", &a, &op, &b);
    switch (op) {
        case '+':
            printf("%lld\n", a + b);
            break;
        case '-':
            printf("%lld\n", a - b);
            break;
        case '*':
            printf("%lld\n", a * b);
            break;
        case '/':
            if (b == 0) {
                printf("error\n");
            } else {
                printf("%lld\n", a / b);
            }
            break;
        case '%':
            if (b == 0) {
                printf("error\n");
            } else {
                printf("%lld\n", a % b);
            }
            break;
    }
    return 0;
}

ข้อ 8 ชนิดของสามเหลี่ยม

ระดับกลาง เวลาไม่เกิน 1 วินาที

มีไม้สามท่อนยาว A B และ C เซนติเมตร ไม้สามท่อนต่อเป็นสามเหลี่ยมได้ก็ต่อเมื่อผลบวกของความยาวสองท่อนใดๆ ยาวกว่าท่อนที่เหลือเสมอ ถ้าผลบวกเท่ากับท่อนที่เหลือพอดี ไม้จะนอนราบเป็นเส้นตรง ไม่นับว่าเป็นสามเหลี่ยม

ถ้าต่อเป็นสามเหลี่ยมได้ ให้บอกชนิดของสามเหลี่ยมด้วย

  • equilateral ด้านเท่ากันทั้งสามด้าน
  • isosceles มีด้านเท่ากันสองด้านพอดี
  • scalene ไม่มีด้านใดเท่ากันเลย

ข้อมูลเข้า

บรรทัดเดียว มีจำนวนเต็ม A B C คั่นด้วยช่องว่าง โดยที่ 1 ≤ A, B, C ≤ 1000000000

ข้อมูลออก

พิมพ์ not a triangle ถ้าต่อเป็นสามเหลี่ยมไม่ได้ ไม่อย่างนั้นพิมพ์ชนิดของสามเหลี่ยม

3 4 5
scalene
2 2 3
isosceles
ดูคำใบ้

ตรวจก่อนว่าเป็นสามเหลี่ยมได้ไหม ต้องเช็กครบทั้งสามคู่ เพราะด้านที่ยาวที่สุดอาจอยู่ตำแหน่งไหนก็ได้ ถ้าเป็นไม่ได้ให้ตอบทันที อย่าดูด้านเท่ากันก่อน เพราะ 1 1 3 มีด้านเท่ากันแต่ไม่ใช่สามเหลี่ยม เวลาเช็กด้านเท่ากันสองด้าน ต้องดูให้ครบทั้งสามคู่เช่นกัน ผลบวกสองด้านมากสุด 2 × 109 ยังเก็บใน int ได้ตามตารางในหน้า 1.3

ดูเฉลย
#include <stdio.h>

int main()
{
    int a, b, c;
    scanf("%d %d %d", &a, &b, &c);
    if (a + b <= c || a + c <= b || b + c <= a) {
        printf("not a triangle\n");
    } else if (a == b && b == c) {
        printf("equilateral\n");
    } else if (a == b || b == c || a == c) {
        printf("isosceles\n");
    } else {
        printf("scalene\n");
    }
    return 0;
}

ข้อ 9 ค่าน้ำประปา

ระดับยาก เวลาไม่เกิน 1 วินาที

การประปาของเมืองหนึ่งคิดค่าน้ำแบบขั้นบันได ราคาของแต่ละหน่วยขึ้นกับว่าเป็นหน่วยที่เท่าไร

หน่วยที่ราคาต่อหน่วย
1 ถึง 108 บาท
11 ถึง 3012 บาท
31 ขึ้นไป20 บาท

เช่น ใช้น้ำ 25 หน่วย 10 หน่วยแรกคิดหน่วยละ 8 บาท และอีก 15 หน่วยคิดหน่วยละ 12 บาท รวม 260 บาท

นอกจากนี้ การประปาเก็บค่าน้ำขั้นต่ำเดือนละ 50 บาท ถ้าคิดตามตารางแล้วได้ไม่ถึง 50 บาท รวมถึงเดือนที่ไม่ได้ใช้น้ำเลย ให้เก็บ 50 บาท

ข้อมูลเข้า

บรรทัดเดียว มีจำนวนเต็ม N คือจำนวนหน่วยที่ใช้ในเดือนนั้น โดยที่ 0 ≤ N ≤ 1000000

ข้อมูลออก

ค่าน้ำที่ต้องจ่ายเป็นบาท

25
260
4
50
ดูคำใบ้

คิดแบบเดียวกับค่าไฟในหน้า 3.2 แต่ละขั้นคิดด้วยราคาของขั้นนั้นเท่านั้น ขั้นที่ใช้เต็มแล้วเป็นค่าคงที่ คือ 10 × 8 และ 20 × 12 คิดค่าน้ำเสร็จแล้ว ค่อยใช้ if อีกตัวตรวจขั้นต่ำ 50 บาท ลองป้อน 6 7 10 11 30 31 แล้วดูว่าค่าน้ำเพิ่มทีละเท่าราคาของขั้นนั้นจริง

ดูเฉลย
#include <stdio.h>

int main()
{
    int units;
    scanf("%d", &units);
    int bill;
    if (units <= 10) {
        bill = units * 8;
    } else if (units <= 30) {
        bill = 10 * 8 + (units - 10) * 12;
    } else {
        bill = 10 * 8 + 20 * 12 + (units - 30) * 20;
    }
    if (bill < 50) {
        bill = 50;
    }
    printf("%d\n", bill);
    return 0;
}

ข้อ 10 วันพรุ่งนี้

ระดับยาก เวลาไม่เกิน 1 วินาที

กำหนดวันที่ D เดือน M ปี Y มาให้ ให้หาว่าวันถัดไปคือวันที่เท่าไร เดือนอะไร ปีอะไร

จำนวนวันในแต่ละเดือนเหมือนข้อจำนวนวันในเดือน คือเดือน 4 6 9 11 มี 30 วัน เดือน 2 มี 29 วันในปีอธิกสุรทิน และ 28 วันในปีอื่น เดือนที่เหลือมี 31 วัน ปีอธิกสุรทินคือปีที่หารด้วย 4 ลงตัวแต่หารด้วย 100 ไม่ลงตัว หรือปีที่หารด้วย 400 ลงตัว ใช้กฎนี้กับทุกปี

ข้อมูลเข้า

บรรทัดเดียว มีจำนวนเต็ม D M Y คั่นด้วยช่องว่าง เป็นวันที่ที่มีอยู่จริง โดยที่ 1 ≤ Y ≤ 9999 และรับประกันว่าไม่ใช่วันที่ 31 เดือน 12 ปี 9999

ข้อมูลออก

วัน เดือน และปีของวันถัดไป คั่นด้วยช่องว่าง ในรูปแบบเดียวกับข้อมูลเข้า

14 2 2025
15 2 2025
31 12 2024
1 1 2025
ดูคำใบ้

แบ่งเป็นสองขั้น ขั้นแรกหาว่าเดือนนี้มีกี่วัน แบบเดียวกับข้อจำนวนวันในเดือน ขั้นที่สองถ้าวันนี้ยังไม่ใช่วันสุดท้ายของเดือน แค่เพิ่มวันหนึ่งวัน ถ้าเป็นวันสุดท้าย วันกลับเป็น 1 แล้วเลื่อนเดือน และถ้าเดือนเป็น 12 ต้องเลื่อนปีด้วย ทดสอบกับ 28 และ 29 กุมภาพันธ์ทั้งปีปกติและปีอธิกสุรทิน และ 31 ธันวาคม

ดูเฉลย
#include <stdio.h>

int main()
{
    int day, month, year;
    scanf("%d %d %d", &day, &month, &year);
    int days_in_month;
    switch (month) {
        case 2:
            if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
                days_in_month = 29;
            } else {
                days_in_month = 28;
            }
            break;
        case 4:
        case 6:
        case 9:
        case 11:
            days_in_month = 30;
            break;
        default:
            days_in_month = 31;
    }
    if (day < days_in_month) {
        day++;
    } else {
        day = 1;
        if (month < 12) {
            month++;
        } else {
            month = 1;
            year++;
        }
    }
    printf("%d %d %d\n", day, month, year);
    return 0;
}