算法競賽中提交答案題、交互題、通信題簡介和答題方法(沒寫完)


算法競賽中提交答案題、交互題、通信題簡介和答題方法

提交答案題

簡介

提交答案題不需要你提交源代碼,只需要提交答案文件。

這類題目一般會先把輸入數據打包到下發文件里給你,交題的時候按照題目要求進行命名並放(提交)到指定位置。

答題方法

一般來講可能比較人類智慧,應該會給手玩的分數,可以手玩出幾組然后其他的寫程序跑或找規律等等。

注意這種情況下寫程序不需要執着在一秒或五秒內得到結果,事實上只要能在考試結束前得到答案都是可接受的。

例子

洛谷 P1008 三連擊

交互題

簡介

交互題,顧名思義,要求你的程序與命題人的程序(通常稱為交互庫)進行互動,來解決問題。

一般交互題的命題意圖:(僅為個人經驗,供參考)

  • 解決實際問題。你不能獲得所有的信息,只能通過若干個給出的接口向交互庫提出問題,來得到你需要的答案。
  • 強制在線。強制在線一般有兩種方式,對輸入數據進行加密(常為異或上次答案),或者進行交互。交互題的特點決定了你每次只能獲取一次詢問,並返回答案,才能獲取下一次詢問。
  • 國外信息學競賽(例如 APIO)的題目往往不用你實現整個程序,而是實現幾個接口函數,這類題目與交互題類似。
  • 雖然這是道傳統題,但我就是要出成交互,我愛交互!!1 ← 這種出題人……這題出的很好,下次別出了,祝 TA 身體健康。

一般交互題的形式有兩種:

  • Grader 交互(函數式交互):給你提供幾個函數接口,向交互庫提問時調用;同時你需要實現幾個函數接口,供評測時獲取你的答案用。
  • I/O 式交互:通過標准輸出流向交互庫提問或給出答案,從標准輸入流讀入輸入信息和提問的回答。

Grader 交互(函數式交互)

題目會給你一個必須包含的頭文件和幾個函數接口,你需要實現另外要求的函數接口。

一般來講好的題目描述會通過如下方式給出:(僅為舉例,不一定有實際意義)

  • 請在程序中包含 array.h 頭文件。
  • 你可以調用一個函數 int compare(int x, int y),返回值為:若 \(x < y\),返回 \(-1\);若 \(x = y\),返回 \(0\);若 \(x > y\),返回 \(1\)(這個函數接口沒啥意義,但是一個挺好的例子)。
  • 你需要實現一個函數 void init(vector<int> A, int n),接收輸入數據。這個函數會在程序開始時被調用恰好一次。
  • 你需要實現一個函數 int find_minimum(int l, int r),返回值為 \(A\) 中下標在 \([l, r]\) 的數中最小數的值。這個函數會被調用不超過 \(q\) 次。

此時你可以實現下面一個程序:

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

void init(vector<int> A, int n) {
    ; // 什么都不做
}
int find_minimum(int l, int r) {// 這么做是沒有意義的,只是一個例子
    if(compare(l, r)) return 0; // 當區間長度大於 1 時,返回 0
    return 1;                   // 當區間只有一個數時,返回 1
}

注意你不需要,也不應當實現主函數。

在提交前仔細檢查是否包含頭文件、是否刪掉了主函數。

Grader 交互(函數式交互)例子

洛谷 P1947 猜數 以及 [APIO 的所有題](https://www.luogu.com.cn/problem/list?tag=85&page=1&orderBy=pid&order=desc(但是洛谷好多 APIO 都被改成傳統題了。。)。

請注意這個例子與實際比賽中 Grader 交互題的不同:因為洛谷交互題實現原因,這道題沒有要求包含頭文件,而實際比賽中往往需要。

I/O 式交互

這類交互在實際比賽中較少用到(除了 CodeForces 等線上平台的比賽),建議重點掌握 Grader 交互,當然以防萬一這種也要會。

題目會給你你的詢問方式,並給出你答題的方式。

舉一個猜數的例子:

  • 首先你要讀入一個整數 \(n\),表示待猜的數在 \([1, n]\) 中。
  • 你可以通過 ? x 的方式向交互庫提問,隨后讀入一個整數表示回答。如果 \(x\) 小於待猜的數,交互庫回答 \(-1\);如果 \(x\) 等於待猜的數,交互庫回答 \(0\);如果 \(x\) 大於待猜的數,交互庫回答 \(1\)
  • 當你猜出這個數后,你可以通過 ! x 給出答案,\(x\) 即為這個數。

注意 I/O 交互中你每次輸出需要刷新輸出緩沖區,對於 C/C++ 語言可以 fflush(stdout);,對於 C++ 語言可以 cout<<endl;

你可以實現這樣的程序:

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

int main() {
    int n;
    scanf("%d", &n);
    for(int i=1;i<=n;i++) {
        printf("? %d\n", i);
        fflush(stdout);
        int x;
        scanf("%d", &x);
        if(!x) {
            printf("! %d\n", i);
            return 0;
        }
    }
    return 0;
}

當然這個程序會超時,只是作為例子我懶得寫二分。

I/O 式交互例子

洛谷 P1733 猜數 以及 CF 上的大多數交互題

通信題

這個我還沒咋見過,先不寫了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM