Giải chi tiết các bài toán Codeforces 918 (Div 4)

Problem A - Tìm phần tử khác biệt

Cho ba số nguyên a, b, c. Trong đó có hai số bằng nhau, cần tìm số còn lại.

Giải thuật: Kiểm tra các cặp bằng nhau, nếu a == b thì đáp án là c, tương tự cho các trường hợp khác.

#include<bits/stdc++.h>
using namespace std;

int main()
{
    long long test;
    cin >> test;

    while(test--)
    {
        int x, y, z;
        cin >> x >> y >> z;
        
        if(x == y) cout << z << endl;
        else if(x == z) cout << y << endl;
        else cout << x << endl;
    }
    return 0;
}

Problem B - Tìm ký tự còn thiếu

Cho ma trận 3x3 chứa các ký tự A, B, C và dấu '?'. Tìm ký tự thay thế cho dấu '?'.

Giải thuật: Đọc ma trận, xác định vị trí của '?'. Sau đó kiểm tra các ký tự trong cùng hàng để tìm ký tự chưa xuất hiện.

#include<bits/stdc++.h>
using namespace main();

int main()
{
    long long test;
    cin >> test;

    while(test--)
    {
        char grid[4][4] = {0};
        int row, col;
        
        for(int i = 1; i <= 3; i++)
        {
            for(int j = 1; j <= 3; j++)
            {
                cin >> grid[i][j];
                if(grid[i][j] == '?')
                {
                    row = i;
                    col = j;
                }
            }
        }
        
        bool hasA = false;
        bool hasB = false;
        bool hasC = false;
        
        for(int j = 1; j <= 3; j++)
        {
            if(grid[row][j] == 'A') hasA = true;
            if(grid[row][j] == 'B') hasB = true;
            if(grid[row][j] == 'C') hasC = true;
        }
        
        if(!hasA) cout << "A" << endl;
        else if(!hasB) cout << "B" << endl;
        else cout << "C" << endl;
    }
    return 0;
}

Problem C - Kiểm tra tổng là số chính phương

Cho mảng gồm m phần tử, tính tổng và kiểm tra xem tổng đó có phải là số chính phương hay không.

Lưu ý: Cần sử dụng long long để tránh tràn số. Cách kiểm tra số chính phương: lấy căn bậc 2, sau đó bình phương lại so sánh.

#include<bits/stdc++.h>
using namespace std;

bool isPerfectSquare(long long val)
{
    long long root = sqrt(val);
    return root * root == val;
}

int main()
{
    long long test;
    cin >> test;

    while(test--)
    {
        long long m;
        cin >> m;
        long long total = 0;
        
        for(int i = 1; i <= m; i++)
        {
            long long num;
            cin >> num;
            total += num;
        }
        
        if(isPerfectSquare(total)) cout << "Yes" << endl;
        else cout << "No" << endl;
    }
    return 0;
}

Problem D - Nhóm nguyên âm và phụ âm

Cho một chuỗi chỉ gồm các chữ cái thường. Cần chia chuỗi thành các nhóm theo quy tắc: mỗi nhóm kết thúc bằng phụ âm và không quá 3 ký tự. Đọc từ phải sang trái để xử lý dễ hơn.

Giải thuật: Duyệt từ cuối chuỗi. Nếu gặp CVC (Phụ âm - Nguyên âm - Phụ âm) thì tách nhóm 3 ký tự. Nếu gặp CV (Nguyên âm - Phụ âm) thì tách nhóm 2 ký tự.

#include <bits/stdc++.h>
using namespace std;

char vowels[] = {'a', 'e'};
char consonants[] = {'b', 'c', 'd'};

bool isVowel(char ch)
{
    for(int i = 0; i < 2; i++)
        if(vowels[i] == ch) return true;
    return false;
}

bool isConsonant(char ch)
{
    for(int i = 0; i < 3; i++)
        if(consonants[i] == ch) return true;
    return false;
}

int main()
{
    int t;
    cin >> t;

    while(t--)
    {
        int n;
        cin >> n;
        
        string input;
        cin >> input;
        
        string result;
        
        for(int i = n - 1; i >= 0; i--)
        {
            result.push_back(input[i]);
            
            if(isConsonant(input[i]) && isVowel(input[i-1]) && isConsonant(input[i-2]))
            {
                result.push_back(input[i-1]);
                result.push_back(input[i-2]);
                result.push_back('.');
                i -= 2;
            }
            else if(isVowel(input[i]) && isConsonant(input[i-1]))
            {
                result.push_back(input[i-1]);
                result.push_back('.');
                i -= 1;
            }
        }
        
        for(int i = result.size() - 2; i >= 0; i--)
            cout << result[i];
        
        cout << endl;
    }

    return 0;
}

Problem E - Tìm dãy con với tổng chẵn lẻ bằng nhau

Tìm một đoạn con sao cho tổng các phần tử ở vị trí lẻ bằng tổng các phần tử ở vị trí chẵn.

Giải thuật: Tính tổng lũy tiến với quy tắc: cộng phần tử lẻ, trừ phần tử chẵn. Nếu tổng bằng 0 hoặc giá trị tổng đã xuất hiện trước đó thì tìm được dãy con thỏa mãn.

Công thức: a[l] + a[l+2] + ... = a[l+1] + a[l+3] + ...

Biến đổi: a[l] - a[l+1] + a[l+2] - a[l+3] + ... = 0

#include <bits/stdc++.h>
using namespace std;

const int MAXN = 1e6 + 10;
int arr[MAXN];

int main()
{
    int t;
    cin >> t;

    while(t--)
    {
        int n;
        cin >> n;
        
        for(int i = 1; i <= n; i++) cin >> arr[i];
        
        long long prefix = 0;
        map<long long, int> seen;
        bool found = false;
        
        for(int i = 1; i <= n; i++)
        {
            if(i % 2 == 1) prefix += arr[i];
            else prefix -= arr[i];
            
            if(prefix == 0 || seen[prefix])
            {
                cout << "Yes" << endl;
                found = true;
                break;
            }
            else
            {
                seen[prefix] = 1;
            }
        }
        
        if(!found) cout << "No" << endl;
    }

    return 0;
}

Thẻ: C++ algorithm Codeforces competitive-programming hash-map

Đăng vào ngày 27 tháng 5 lúc 16:40