No.3084 Identify f(x)
タグ : / 解いたユーザー数 128
作問者 :


ストーリー
ゆ~さんはバーチャルこゃーそ学園で勉強をしている学生です。今日は、「数学2」というテキストを用いて一次関数の学習をするようです。
勉強中にふと、ゆ~さんは呟きました。
「うーん、つかれた...息抜きしたい...」
先生はそれを聞いて言いました。
「それじゃあ、「関数あてゲーム」というのをやってみようか。せっかくだし、競プロの問題にしちゃうね。競プロは息抜き、でしょ?」
問題文
この問題はインタラクティブな問題(あなたが作成したプログラムとジャッジプログラムが標準入出力を介して対話を行う形式の問題)です。
関数 $f$ は整数 $a,b$ を用いて $f(x) = ax+b$ と表せることが分かっています。
$a,b$ の値は与えられませんが、$a,b$ 共に $-100$ 以上 $100$ 以下であることが制約より保証されます。
以下の形式の質問を最大 $100$ 回行ってもよいです。$a,b$ を特定してください。
- $-1000$ 以上 $1000$ 以下の整数を一つ選び $x$ とする。$f(x)$ の値を尋ねる。
入出力
この問題はインタラクティブな問題(あなたが作成したプログラムとジャッジプログラムが標準入出力を介して対話を行う形式の問題)です。
はじめ、入力は与えられません。
あなたは以下の質問を最大 $100$ 回行うことができます。
- $-1000$ 以上 $1000$ 以下の整数 $x$ の値を出力する。ジャッジに $f(x)$ の値を尋ねる。
上記の質問を行う場合、以下の形式で出力してください。特に、?
(クエスチョンマークと空白)を $x$ の前に出力しなければならないことに注意してください。
? $x$
そして、出力をflushしてください。
出力をflushするとは?
通常、プログラムの標準出力はバッファリングされ、ある程度データがたまるまで出力されません。しかし、インタラクティブな問題の場合「出力を行った際にすぐジャッジに伝わる」必要があります。
そのため、手動でflushを行ってデータがたまるのを待つことなく出力をさせる必要があります。
具体例(Rustでproconioクレートを使用する場合、この項目の確認を推奨します。)
C++の場合
以下は、宣言したint型整数 $x$ を用いて質問を $1$ 回行い、その質問に対応する $R$ を受け取るコードです。(これは、本問題の解法となるコードではありません。)#include<iostream>
using namespace std;
int main(){
int x = 0;
cout << "? " << x << endl;//endlを使用すると自動的にflushされる。
int R;
cin >> R;//R=f(x)を満たすRを受け取る
return 0;
}
Pythonの場合
以下は、宣言した整数 $x$ を用いて質問を $1$ 回行い、その質問に対応する $R$ を受け取るコードです。(これは、本問題の解法となるコードではありません。)
import sys x = 0 print(f"? {x}")# 改行あり(通常は自動でflushされる) R = int(input())# R=f(x)を満たすRを受け取る
Javaの場合
以下は、宣言したint型整数 $x$ を用いて質問を $1$ 回行い、その質問に対応する $R$ を受け取るコードです。(これは、本問題の解法となるコードではありません。)
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in);// 標準入力の設定 int x = 0; System.out.println("? " + x); // 改行あり(通常は自動でflushされる) int R = sc.nextInt();// R=f(x)を満たすRを受け取る } }
Cの場合
以下は、宣言したint型整数 $x$ を用いて質問を $1$ 回行い、その質問に対応する $R$ を受け取るコードです。(これは、本問題の解法となるコードではありません。)
#include <stdio.h> int main() { int x = 0; printf("? %d\n", x);// この命令ではflushは行われない fflush(stdout);// flushを行う int R; scanf("%d", R)// R=f(x)を満たすRを受け取る return 0; }
Rustの場合
Rustユーザーの場合、proconioクレートを使用することが多いと想定されますが、その場合ジャッジ環境ではリリースビルドとなります。
この場合、入力は「一度に全て読み込む」ようになり、インタラクティブ問題ではジャッジ結果が TLE
となることがあります。
これは、input_interactive!
マクロを使用することで回避が可能です。
以下は、input_interactive!
マクロを使用したうえで、宣言した整数 $x$ を用いて質問を $1$ 回行い、その質問に対応する $R$ を受け取るコードです。(これは、本問題の解法となるコードではありません。)
use proconio::input_interactive; fn main() { let mut x = 0; println!("? {}", x);// 改行あり(通常は自動でflushされる) input_interactive!(R: i64);// R=f(x)を満たすRを受け取る }
Nimの場合
以下は、宣言した整数 $x$ を用いて質問を $1$ 回行うコードです。(これは、本問題の解法となるコードではありません。)
import strutils var x = 0 echo "? ", x # 改行あり(通常は自動でflushされる) var R = readLine(stdin).parseInt()# R=f(x)を満たすRを受け取る
こちらも参照してください。
この質問を行った場合、出力した $x$ に対して $R=f(x)$ を満たす $R$ の値がジャッジから以下の形式で与えられますので、これを標準入力より受け取ってください。(制約より $R$ は必ず整数となることが保証されます。)
$R$
ただし、以下の条件を満たした場合、代わりに -1000000000
$(=-10^9)$ が与えられます。(制約より正当な質問に対する答えとして -100000000
が与えられることはないことが保証されます。)
- 条件を満たさない、または不正な値を出力した。
- 質問回数が $100$ 回を超えた。
このとき、ジャッジはすでに WA
とみなされているためただちにプログラムを終了してください。
質問を繰り返し、 $a,b$ を特定したら、以下の形式で $a,b$ を出力してください。特に、!
(エクスクラメーションマークと空白)を $a$ と $b$ の前に出力しなければならないことに注意してください。
! $a$ $b$
そして、出力をflushし、ただちにプログラムを終了してください。
出力をflushするとは?
通常、プログラムの標準出力はバッファリングされ、ある程度データがたまるまで出力されません。しかし、インタラクティブな問題の場合「出力を行った際にすぐジャッジに伝わる」必要があります。
そのため、手動でflushを行ってデータがたまるのを待つことなく出力をさせる必要があります。
具体例(Rustでproconioクレートを使用する場合、この項目の確認を推奨します。)
C++の場合
以下は、宣言したint型整数 $x$ を用いて質問を $1$ 回行い、その質問に対応する $R$ を受け取るコードです。(これは、本問題の解法となるコードではありません。)#include<iostream>
using namespace std;
int main(){
int x = 0;
cout << "? " << x << endl;//endlを使用すると自動的にflushされる。
int R;
cin >> R;//R=f(x)を満たすRを受け取る
return 0;
}
Pythonの場合
以下は、宣言した整数 $x$ を用いて質問を $1$ 回行い、その質問に対応する $R$ を受け取るコードです。(これは、本問題の解法となるコードではありません。)
import sys x = 0 print(f"? {x}")# 改行あり(通常は自動でflushされる) R = int(input())# R=f(x)を満たすRを受け取る
Javaの場合
以下は、宣言したint型整数 $x$ を用いて質問を $1$ 回行い、その質問に対応する $R$ を受け取るコードです。(これは、本問題の解法となるコードではありません。)
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in);// 標準入力の設定 int x = 0; System.out.println("? " + x); // 改行あり(通常は自動でflushされる) int R = sc.nextInt();// R=f(x)を満たすRを受け取る } }
Cの場合
以下は、宣言したint型整数 $x$ を用いて質問を $1$ 回行い、その質問に対応する $R$ を受け取るコードです。(これは、本問題の解法となるコードではありません。)
#include <stdio.h> int main() { int x = 0; printf("? %d\n", x);// この命令ではflushは行われない fflush(stdout);// flushを行う int R; scanf("%d", R)// R=f(x)を満たすRを受け取る return 0; }
Rustの場合
Rustユーザーの場合、proconioクレートを使用することが多いと想定されますが、その場合ジャッジ環境ではリリースビルドとなります。
この場合、入力は「一度に全て読み込む」ようになり、インタラクティブ問題ではジャッジ結果が TLE
となることがあります。
これは、input_interactive!
マクロを使用することで回避が可能です。
以下は、input_interactive!
マクロを使用したうえで、宣言した整数 $x$ を用いて質問を $1$ 回行い、その質問に対応する $R$ を受け取るコードです。(これは、本問題の解法となるコードではありません。)
use proconio::input_interactive; fn main() { let mut x = 0; println!("? {}", x);// 改行あり(通常は自動でflushされる) input_interactive!(R: i64);// R=f(x)を満たすRを受け取る }
Nimの場合
以下は、宣言した整数 $x$ を用いて質問を $1$ 回行うコードです。(これは、本問題の解法となるコードではありません。)
import strutils var x = 0 echo "? ", x # 改行あり(通常は自動でflushされる) var R = readLine(stdin).parseInt()# R=f(x)を満たすRを受け取る
こちらも参照してください。
制約
- $-100\le a,b \le 100$
- $a,b$ は整数
注意点
- 出力を行うたびに、末尾に改行を入れて標準出力を flush してください。そうしなかった場合、ジャッジ結果がTLEとなる可能性があります。
出力をflushするとは?
通常、プログラムの標準出力はバッファリングされ、ある程度データがたまるまで出力されません。しかし、インタラクティブな問題の場合「出力を行った際にすぐジャッジに伝わる」必要があります。
そのため、手動でflushを行ってデータがたまるのを待つことなく出力をさせる必要があります。
具体例(Rustでproconioクレートを使用する場合、この項目の確認を推奨します。)
C++の場合
以下は、宣言したint型整数 $x$ を用いて質問を $1$ 回行い、その質問に対応する $R$ を受け取るコードです。(これは、本問題の解法となるコードではありません。)#include<iostream> using namespace std; int main(){ int x = 0; cout << "? " << x << endl;//endlを使用すると自動的にflushされる。 int R; cin >> R;//R=f(x)を満たすRを受け取る return 0; }
Pythonの場合
以下は、宣言した整数 $x$ を用いて質問を $1$ 回行い、その質問に対応する $R$ を受け取るコードです。(これは、本問題の解法となるコードではありません。)
import sys x = 0 print(f"? {x}")# 改行あり(通常は自動でflushされる) R = int(input())# R=f(x)を満たすRを受け取る
Javaの場合
以下は、宣言したint型整数 $x$ を用いて質問を $1$ 回行い、その質問に対応する $R$ を受け取るコードです。(これは、本問題の解法となるコードではありません。)
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in);// 標準入力の設定 int x = 0; System.out.println("? " + x); // 改行あり(通常は自動でflushされる) int R = sc.nextInt();// R=f(x)を満たすRを受け取る } }
Cの場合
以下は、宣言したint型整数 $x$ を用いて質問を $1$ 回行い、その質問に対応する $R$ を受け取るコードです。(これは、本問題の解法となるコードではありません。)
#include <stdio.h> int main() { int x = 0; printf("? %d\n", x);// この命令ではflushは行われない fflush(stdout);// flushを行う int R; scanf("%d", R)// R=f(x)を満たすRを受け取る return 0; }
Rustの場合
Rustユーザーの場合、proconioクレートを使用することが多いと想定されますが、その場合ジャッジ環境ではリリースビルドとなります。
この場合、入力は「一度に全て読み込む」ようになり、インタラクティブ問題ではジャッジ結果が
TLE
となることがあります。これは、
input_interactive!
マクロを使用することで回避が可能です。以下は、
input_interactive!
マクロを使用したうえで、宣言した整数 $x$ を用いて質問を $1$ 回行い、その質問に対応する $R$ を受け取るコードです。(これは、本問題の解法となるコードではありません。)use proconio::input_interactive; fn main() { let mut x = 0; println!("? {}", x);// 改行あり(通常は自動でflushされる) input_interactive!(R: i64);// R=f(x)を満たすRを受け取る }
Nimの場合
以下は、宣言した整数 $x$ を用いて質問を $1$ 回行うコードです。(これは、本問題の解法となるコードではありません。)
import strutils var x = 0 echo "? ", x # 改行あり(通常は自動でflushされる) var R = readLine(stdin).parseInt()# R=f(x)を満たすRを受け取る
こちらも参照してください。
- 対話の途中で不正な出力を行った、あるいはプログラムが途中で終了した場合のジャッジ結果は不定です。 特に、プログラムの実行中に実行時エラーが起こった場合に、ジャッジ結果がREではなくWAやTLEになる可能性があることに注意してください。
- 答えを出力したらただちにプログラムを終了してください。そうしない場合、ジャッジ結果は不定です。
- この問題のジャッジは適応的ではありません。すなわち、プログラムが実行された時点で $f(x)=ax+b$ を満たす $(a,b)$ がどのようなものであるかが決まっています。
入出力例
以下はジャッジとの対話例です。下記のような質問をすることで正解となる $a,b$ を必ず求められることを保証するものではない点に注意してください。
プログラムによる出力 | ジャッジから与えられる入力 | 説明 |
---|---|---|
? 1 | ジャッジに $x = 1$ として質問をします。 | |
5 | ジャッジから質問の答えである $5$ が与えられます。 | |
? 6 | ジャッジに $x=6$ として質問をします。 | |
20 | ジャッジから質問の答えである $20$ が与えられます。 | |
? -5 | ジャッジに $x=-5$ として質問をします。 | |
-13 | ジャッジから質問の答えである $-13$ が与えられます。 | |
! 3 2 | この時点で制約より考えられる関数のうち $f(x) = 3x +2$ 以外のものはいずれかのジャッジからの回答と矛盾することが示せます。 したがって$a=3,b=2$を出力します。 |
提出するには、Twitter 、GitHub、 Googleもしくは右上の雲マークをクリックしてアカウントを作成してください。