yukicoder April Fool Contest 2021 No.3077, No.3085
いやー難しかったです(好き
全部は解いていませんし、解いた問題を全て(6つしかないですが)解説すると大変なので2つだけ
E: No.3077 🔧
まず項目があるのに問題文、制約、サンプル等が読めないことに着目します。
きっと読めない状態になっているということです。
ブラウザの開発者ツールを開いてみます。
ビンゴです! なんと問題文が HTML の class 属性名になっていました。
つまり、
- 問題
- a×b+c-d を k で割った余りを出力してください。
- 制約
- 1 <= a, b, c, d, k <= 10^9
- ab + c >= d
- 入力はすべて整数。
- 入力
- $a\ b\ c\ d\ k$
- 出力
- a×b+c-d を k で割った余りを出力してください。最後に改行してください。
ということですね。
制約より、a*b および (a%k)*(b%k) は 32 bit 整数に収まらないですが、
ab + c - d は 64 bit 整数には収まるので、次のように解けます。
#include<iostream> int main(){ long long a,b,c,d,k; std::cin>>a>>b>>c>>d>>k; std::cout<<(a*b+c-d)%k<<"\n"; }
問題文さえ読めれば ABC A問題程度の難易度でしたネ🎃
M: No.3085 Math...?
まず真面目に考えます。
u-sho「愚直?」
u-sho2「間に合わん」
u-sho「じゃあ総和部分の値を保存しておいて」
u-sho2「それでも間に合わないね」
u-sho「演算のいい性質がある?」
u-sho2「具体的に Do you know?」
u-sho「知りません。難しすぎませんか?」
時間切れです。ここで解説をみました。この問題は解けないらしいです。なるほどニャ(?
ところで、問題文の下の空行がやけに多いですね。何かあるんでしょうか?
例により開発者ツールを開いてみます
ありましたね......
font タグ*1の color 属性で white にされているようなので、ここを black に編集して見えるようにしてみます。
Googleドキュメントへのリンクが表示されましたね。
打ち込むのが大変でしょうからここに貼っておきます。
https://docs.google.com/document/d/14UQE9wc6K-YRyN56WYiF6Z7WQ1AkT8qVg17VdWrjeTg/edit?usp=sharing
docs.google.com
しかし、ここにもおかしなことが書いてあります。
1+2+3+4+...+100=5050です。5050を1000000007で割った余りの1を出力してください。
5050 を 1000000007 で割った余りは当然 5050 ですから、これはおかしいですね。
そういえば、サンプルの下の空行がやけに多いですね。何かあるんでしょうか。
ありましたね......
16進数でしょうか。文字列か、最大4桁ということは 64bit 整数かもしれませんね。
とりあえず以下のようなコードを書いて変換してみます。
#include<stdio.h> int main(){ long long c; while(~scanf("%x", &c)) printf("%c", c); }
ascii 範囲外の文字は化けましたが、とりあえず次のような出力になりました
Sn�(https://yukicoder.me/problems/6059)n�OL�e�6go�K�fD�0ojD�nhWf�gO`UD~_�3o6U�n_�ƹȱ�k+~�~[�
明らかに文字列です。つまりこれを UTF16 なりなんなり*2で見てあげればいいわけですね。
C や C++ でこれをやるのは大変な気がしたので、JavaScript を使います。
まず、JavaScript の Unicode リテラル(参考:
文字クラス - JavaScript | MDN
)に変換します。
適当なエディタに先程の文字列をコピペし、[0-9a-f]+ や !\s を \u{$1} のような形に置換すると良いです。
結果はこんな感じ(文字列は適当な長さで分割しています)
const str = "\u{3053}\u{306e}\u{30da}\u{30fc}\u{30b8}" + "\u{28}\u{68}\u{74}\u{74}\u{70}\u{73}\u{3a}\u{2f}\u{2f}" + "\u{79}\u{75}\u{6b}\u{69}\u{63}\u{6f}\u{64}\u{65}" + "\u{72}\u{2e}\u{6d}\u{65}\u{2f}\u{70}\u{72}\u{6f}" + "\u{62}\u{6c}\u{65}\u{6d}\u{73}\u{2f}\u{36}\u{30}" + "\u{35}\u{39}\u{29}\u{306e}\u{5185}\u{3001}" + "\u{554f}\u{984c}\u{6587}\u{3001}\u{5165}" + "\u{529b}\u{3001}\u{5236}\u{7d04}\u{3067}" + "\u{306f}\u{3001}\u{66f8}\u{304b}\u{308c}" + "\u{3066}\u{3044}\u{308b}\u{30}\u{306f}\u{306a}" + "\u{3044}\u{3082}\u{306e}\u{3068}\u{3057}" + "\u{3066}\u{8aad}\u{3093}\u{3067}\u{304f}" + "\u{3060}\u{3055}\u{3044}\u{3002}\u{307e}" + "\u{305f}\u{3001}\u{30b5}\u{30f3}\u{30d7}\u{30eb}" + "\u{33}\u{306f}\u{5236}\u{7d04}\u{9055}\u{53cd}" + "\u{306e}\u{305f}\u{3081}\u{30c6}\u{30b9}\u{30c8}" + "\u{30b1}\u{30fc}\u{30b9}\u{306b}\u{542b}" + "\u{307e}\u{308c}\u{307e}\u{305b}\u{3093}\u{3002}"
そしてこれを console.log してあげれば良いわけです。
はい、出てきましたね。
このページ(https://yukicoder.me/problems/6059)の内、問題文、入力、制約では、書かれている0はないものとして読んでください。また、サンプル3は制約違反のためテストケースに含まれません。
なるほどです(元の問題文なんだったっけ←)
つまり元の問題文
正整数 が与えられるので、 を で割った余りを出力してください。この問題は ケース与えられます。
入力、制約
- 入力は全て整数
は次のようになるということですね。
- 問題
- 正整数 が与えられるので、(制約より、)を で割った余りを出力してください。この問題は ケース与えられます。
- 制約
- 入力は全て整数
- つまり
- つまり
ゆえに
#include<iostream> int main(){ int Q, A, B; std::cin >> Q >> A >> B; long long sum = 0; for (int i=1; i<B; i++) sum += i; std::cout << sum << "\n"; }
となります。
ゴルフ
ところで、 であることが知られています(参考:等差数列の和の公式の例題と証明など | 高校数学の美しい物語)
なので、C(gcc) でコードゴルフをすると次のようにも書けます。
B;main(){scanf("%d%d%d",&B,&B,&B);printf("%d",B++*B/2%17);}
2021/4/2 17:06 時点で Bash に次いで2番目です(お行儀の悪い提出をしています。ごめんなさい)
ruby とかも結構短く書けるはずなので皆さんもお試しあれ
以上
ばいちゃ!