ABC 139
- 順位:806位
- パフォーマンス:1472
- レーティング:1131→ 1172(+41)
A-Tenki
S[i]が等しい時T[i]でans++
B-Power Socket
B以上になるまでA-1を足していく
C-Lower
H[i-1]>=H[i]のときcnt++, H[i-1]<H[i]のときcnt = 0としてcntの最大値
D-ModSum
一瞬で答えがわからなかったため, Eを先にやったが, 時間切れで解けなかった
E-League
実際にシュミュレーションさせる
各日でO(N)かけて最悪計算量がO()となり6ペナ
しかし, 前日で試合した人だけを見れば良いことがわかるので, O()で解ける
なめらかなライントレースを目指して その1
初めに
反射型フォトインタラプタを8つ使用し,実際の角度と読み取る角度が線形に取れることを目標とします.
フォトインタラプタの性質
フォトインタラプタは赤外線発光素子と受光素子からなり,受光素子が光を受け取ると低い電圧,光を受け取らないと高い電圧を出します.
実際に黒い線を通過させた時の電圧の変化は次のようになります.
真ん中の電圧値が大きくなっているところが黒い線の上を通っている時になります.
本題
今回はフォトインタラプタを8つ使用するのでこれを並べて表示すると次のようになります.
見てわかる通り,フォトインタラプタ一つ一つの個体差があるので,最大の値が異なっています. これではやりづらいので,次のように正規化します
for(int i = 0; i < FOT_NUM; i++){ light[i] = map(analogRead(i), minlight[i], maxlight[i], MINLIGHT, MAXLIGHT); light[i] = constrain(light[i], MINLIGHT, MAXLIGHT); }
このようにすると
のようになり,扱いやすくなります.
まず,最大の電圧値を取ったフォトインタラプタの左右の電圧値の差deg
を出します.
そうすると,今回は次のような波形になりました.
この波形は,フォトインタラプタの間隔によっても変化します.
この波形は,多項式関数によく似ているので1/n乗してあげます. ただし,Arduinoはマイナスの値は1/n乗出来ないようなので,絶対値を取ってあげてから1/n乗します.
ここで,直線になってくれれば問題なかったのですが,nを変化させても直線になりませんでした. しかし,真ん中部分の0に落ちている所を除くとcosの波形によく似ているので次のように正規化すると.
// mymap double mymap(double x, double in_min, double in_max, double out_min, double out_max){ return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } // main value = mymap(deg, 1, 5.5, -1, 1); value = constrain(value, -1, 1);
このようにcosのような波形になったので,arccosをとると
こうなります.
ここで,頂点より左側と右側でdeg
がマイナスとプラスで異なっていることを利用すると
一つ直線が出来ました. これを上手に並べることで
のようになり,目標を達成することが出来ました.
おわりに
今回は数式に則って曲線を直線に変形したわけでなく,試行錯誤しながらそれらしくしていったので,フォトインタラプタの間隔が違った時どうなるかわからないなどの課題が残っている