iT邦幫忙

1

OJ上如何讀測資的教學?

大家好,我是心原一馬,
今天要帶大家學習如何在oj上讀測資啦
(不知道oj的同學可參考學外語尚且知道要跟外國人練習會話; 學程式語言,怎能沒有練功平台?心原一馬盤點六個刷題網站這篇)

練習zerojudge常常會需要讀取測資,例如:
讀入一個整數n,
下一行會讀入n個整數

由於這個功能實在太常用到了,
覺得值得寫一篇文章來記錄常見的讀測資的程式碼

一、輸入一個數字n,接下來輸入n行,每行一個數字

<C>

#include <stdio.h>
int main(){
    int n, i;
    scanf("%d", &n);
    for(i=0; i<n; i++){
        int t;
        scanf("%d", &t);
        //do something
    }
    return 0;
}

<c++>

#include <iostream>
int main(){
    int n;
    std::cin >> n;
    for(int i=0; i<n; i++){
        int t;
        std::cin >> t;
        //do something
    }
    return 0;
}

<python>

n = int(input())
for i in range(n):
    t = int(input())
    # do something

二、輸入一個數字n,接下來輸入一行n個數字,表示一個陣列

<C++>

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

int main(){
    
    int n;
    std::cin >> n;
    std::vector<int> arr(n);
    for(int i=0; i<n; i++){
        std::cin >> arr[i];
    }
    //do something
    for(int i=0; i<n; i++){
        std::cout << arr[i]<<" ";
    }
    std::cout  << std::endl;
    return 0;
}

<python>

n = int(input()) #第一行讀的數字其實用不到,因為python讀陣列可不必事先知道幾個數
nums = list(map(int, input().split())) #讀數字列表  

三、輸入一個數字n,接下來有n行字串要讀

<C++>

#include <iostream>
using namespace std;

int main(){
    
    int n;
    cin >> n;
    cin.ignore(); // 重要: 把第一個換行符號吃掉,不然會被getline()讀到
    string s;
    for(int i=0; i<n; i++){
        getline(cin,s);
        cout << s << endl;
    }
    return 0;
}

<python>

n = int(input())
for i in range(n):
    s = input()
    # do something

四、讀取測資直到EOF(end of file,表示程式輸入的結束)

<c>

#include <stdio.h>
int main()
{
    int value;
    while(scanf("%d", &value)!= EOF){
        //do something
    }
    return 0;
}

<c++>

#include <iostream>
int main()
{
    int value;
    while(std::cin >> value){
        //do something
    }
    return 0;
}

<python>

# Note: 在zerojudge上,python可以這樣讀資料
# 至於try區塊內用哪一種方式讀資料視題目需求
while True:
    try:
        nums = list(map(int, input().split())) #讀數字列表
        s = input() #單純讀一行字串
        n = int(input()) #單純讀一個數字
    except: break

五、讀取兩個數字n, m,接下來有n行,每行m個數字,代表一個二維陣列

<c++>

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

int main(){
    
    int n, m;
    std::cin >> n >> m;
    vector<vector<int>> arr(n, vector<int>(m));
    for(int i=0; i<n; i++){
        for (int j = 0; j < m; j++) {
            std::cin >> arr[i][j];
        }
    }
    //do something
    for(int i=0; i<n; i++){
        for (int j = 0; j < m; j++) {
            cout << arr[i][j] << " ";
        }
        cout << endl;
    }
    cout << endl;
    return 0;
}

最後,再告訴大家一個oj上讀寫的小技巧,
通常oj上會有所謂的「程式時間限制」,
你的程式必須在限定時間內(譬如1秒鐘)跑出結果,
否則會TLE(Time Limit Exceed,執行時間超過限制)

實測發現,使用C的scanf, printf函數來做讀寫,
通常會比使用c++的cin, cout函數來的快,
如果在oj上發生TLE的狀況,
也不妨試著將cin, cout函數改成用scanf, printf


尚未有邦友留言

立即登入留言