---
# System prepended metadata

title: AtCoder Beginner Contest 266

---

---
title: 'AtCoder Beginner Contest 266'
disqus: hackmd
---

AtCoder Beginner Contest 266
===

[TOC]
## string [A - Middle Letter](https://atcoder.jp/contests/abc266/tasks/abc266_a)
:::info
輸出中間那個數。
:::
```csharp=
#include <bits/stdc++.h>
using namespace std;
#define ll long long 
#define N 1e9
 
int main() {
  ios::sync_with_stdio(false); 
  cin.tie(0);
  string s;
  cin>>s;
  cout<<s[s.size()/2]<<'\n';
  return 0;
}
```
## mod [B - Modulo Number](https://atcoder.jp/contests/abc266/tasks/abc266_b)
:::info
x=n+k倍的MOD(998244353)，所以加到變成正數，再模MOD。
k慢慢跑會TLE(次數至多=$10^{18}/MOD+1$)，所以設定k每跑一次，k會變成前一次的k*2。
:::
```csharp=
#include <bits/stdc++.h>
using namespace std;
#define ll long long 
#define MOD 998244353
 
int main() {
  ios::sync_with_stdio(false); 
  cin.tie(0);
  ll n;
  cin>>n;
  for(ll i=1;i<1000000000;i*=2){
    if(n>MOD) break;
    n+=i*MOD;
  }
  cout<<(n-MOD)%MOD;
  return 0;
}
```
## dp [D - Snuke Panic (1D)](https://atcoder.jp/contests/abc266/tasks/abc266_d)
:::info
開兩個陣列x[t]、a[t]，記錄在t時刻的蟲座標及果實大小。
這題看起來就很dp[i][j] (前後位置有關)，那就來嘗試用dp解吧!
先思考dp[i][j]如何定義
* 定義dp[i][j]是在位置為i、時刻為j時，所能吃到最大size的蟲。

i介於0~4、j 介於0~$10^5$，所以設定陣列大小為dp[5][n]，
再來思考dp[i][j]可能由何者遞迴得到
1. dp[i][j-1]而得(站在原地一秒鐘)
2. dp[i-1][t-1]而得(往右走一步)
3. dp[i+1][t-1]而得(往左走一步)

最後把上面三個取max=dp[i][j]。
記得在dp[i][j]的時刻及位置可以吃到a[t]大小的蟲，要加上去。
最後所求=時刻為$10^5$，在每個位置所能吃到的最大size。
:::
:::danger
注意下面的code:t跟i不能顛倒，不然會產生吃了又吃的問題。
:::
```csharp=
#include <bits/stdc++.h>
using namespace std;
#define ll long long 
#define n 100010
ll t,x[n],a[n],dp[n];
int main() {
  ios::sync_with_stdio(false); 
  cin.tie(0);
  ll maxi=0;
  ll dp[5][n]; 
  for(ll i=1;i<5;i++) dp[i][0]=-1e18;
  ll N;
  cin>>N;
  for(ll i=0;i<N;i++){
    cin>>t;//t->唯一的x[t]、a[t]
    cin>>x[t]>>a[t];
  }
  for(ll t=1;t<=100000;t++){
	for(ll i=0;i<5;i++){
	    dp[i][t]=dp[i][t-1];
		if(i!=0)dp[i][t]=max(dp[i][t],dp[i-1][t-1]);
		if(i!=4)dp[i][t]=max(dp[i][t],dp[i+1][t-1]);
	}
	dp[x[t]][t]+=a[t];
}
  for(ll i=0;i<5;i++) maxi=max(maxi,dp[i][100000]);
  cout<<maxi<<'\n';
  return 0;
}
```
## 遞迴 [E - Throwing the Die](https://atcoder.jp/contests/abc266/tasks/abc266_e) 
:::info
這題的關鍵在於構造遞迴關係式，我們來思考
1. 第1回合的期望值=f(1)=1*$\frac{1}{6}$+2*$\frac{1}{6}$+3*$\frac{1}{6}$+4*$\frac{1}{6}$+5*$\frac{1}{6}$+6*$\frac{1}{6}$+=3.5
2. 第2回合的期望值=f(2)=max(1,f(1))$\frac{1}{6}$+max(2,f(1))$\frac{1}{6}$+max(3,f(1)) $\frac{1}{6}$+max(4,f(1))*$\frac{1}{6}$+max(5,f(1))$\frac{1}{6}$+max(6,f(1))$\frac{1}{6}$+=4.25
(覺得骰子點數太少就再投一次，
期望拿到max(本次可能投擲的點數,投擲前一次的期望值)$\frac{1}{6}$點
3. 由2.可觀察出遞迴關係式:f(n)=max(i,f(n-1)),i=1~6

如果直接用f(n)下去遞迴到f(1)=3.5會發生一件事情:f(n)無法被確定，無法直接return f(n-1)(因為還要比大小)=>所以要先建表f(n)。
那不如反過來做，從x=1遞迴到x=n。
而從轉移式可知:我們只需要兩個變數紀錄f(n)、f(n-1)即可，所以開x,y分別記錄兩者，完整程式碼如下。
:::
:::danger
如何cout浮點數到小數點下第n位置:
利用cout<<fixed<<setprecision(10)<<數字/變數<<'\n';
:::
```csharp=
#include <bits/stdc++.h>
using namespace std;
#define ll long long 
#define max(p,q)((p)>(q)?(p):(q))
#define N 1e9
int main() {
  ios::sync_with_stdio(false); 
  cin.tie(0);
  ll n;
  double x=3.5,y;//x=f(x),y=f(x-1)
  cin>>n;
  for(ll i=2;i<=n;i++){
    y=0;
    for(ll j=1;j<=6;j++){
      y+=max(j,x)/6;
    }
    x=y;//交換
  }
  cout<<fixed<<setprecision(10)<<x<<'\n';
  return 0;
}
```