AtCoder abc 189 题解
A、判断三个字符是否相等,水题
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 1e6 + 7; 5 const ll mod = 1e9 + 7; 6 7 int main() 8 { 9 string s; 10 cin >> s; 11 if (s[0] == s[1] && s[1] == s[2])cout << "Won\n"; 12 else cout << "Lost\n"; 13 return 0; 14 }
B、遍历,水题
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 1e6 + 7; 5 const ll mod = 1e9 + 7; 6 7 int main() 8 { 9 int n, x; 10 cin >> n >> x; 11 int ans = -1; 12 ll cnt = 0; 13 for(int i = 0; i < n; ++i){ 14 int a, b; 15 cin >> a >> b; 16 cnt += a * b; 17 if(ans == -1){ 18 if(cnt > x * 100)ans = i + 1; 19 } 20 } 21 cout << ans << "\n"; 22 return 0; 23 }
C、针对每一个位置,分别向左、向右找到离当前位置最近的、且值小于当前值的位置,假设当前找到的左右位置为l, r, 那么当前的取值为A[i] * (r- l - 1),遍历取max即可。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 1e6 + 7; 5 const ll mod = 1e9 + 7; 6 7 int ar[maxn], l[maxn], r[maxn]; 8 int main() 9 { 10 int n; 11 cin >> n; 12 for(int i = 1; i <= n; ++i)cin >> ar[i]; 13 vector<pair<int, int>> pa; 14 pa.push_back(make_pair(0, 0)); 15 for(int i = 1; i <= n; ++i){ 16 while(pa.back().first >= ar[i])pa.pop_back(); 17 l[i] = pa.back().second; 18 pa.push_back(make_pair(ar[i], i)); 19 } 20 while(pa.size() > 0)pa.pop_back(); 21 pa.push_back(make_pair(0, n + 1)); 22 for(int i = n; i >= 1; --i){ 23 while(pa.back().first >= ar[i])pa.pop_back(); 24 r[i] = pa.back().second; 25 pa.push_back(make_pair(ar[i], i)); 26 } 27 ll ans = 0; 28 for(int i = 1; i <= n; ++i){ 29 //cout << ar[i] << ' ' << l[i] << ' ' << r[i] << '\n'; 30 ans = max(ans, 1LL * ar[i] * (r[i] - l[i] - 1)); 31 } 32 cout << ans << '\n'; 33 return 0; 34 }
D、维护两个数组,即当前位置取值分别为True和False的组合的数量,遍历,则答案为最后一个位置取值为True的数量。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 1e6 + 7; 5 const ll mod = 1e9 + 7; 6 7 ll a[maxn], b[maxn]; 8 int main() 9 { 10 int n; 11 cin >> n; 12 a[0] = b[0] = 1; 13 for(int i = 1; i <= n; ++i){ 14 string s; 15 cin >> s; 16 if(s == "AND"){ 17 a[i] = 2 * a[i - 1] + b[i - 1]; 18 b[i] = b[i - 1]; 19 } 20 else{ 21 a[i] = a[i - 1]; 22 b[i] = a[i - 1] + 2 * b[i - 1]; 23 } 24 } 25 cout << b[n] << "\n"; 26 return 0; 27 }
E、维护原始坐标 -> 当前坐标的两个函数。横纵坐标,一个坐标取值对应一个函数。函数可以由一个三元组(a, b, c)组成,a代表当前坐标值映射的是原始的横坐标值还是纵坐标值,b、c分别是坐标值的系数。假如原坐标为(x, y)时,若当前函数的三元组为(0, b, c),则当前值为bx + c;若当函数的三元组为(1, b, c),则当前坐标值为(by + c)。
那么针对每次操作,只需要维护函数对应的三元组即可。
1、顺时针旋转:横轴坐标对换,且纵坐标*=-1。
2、逆时针旋转:横轴坐标对换,且横坐标*=-1。
3、对x=p直线取对称点:纵坐标不变,横坐标从 b 变为 2p - b。即函数三元组从(a, b, c)变为(a, -b, 2p - c)。
4、对y=p直线取对称点:横坐标不变,纵坐标从 b 变为 2p - b。即函数三元组从(a, b, c)变为(a, -b, 2p - c)。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 1e6 + 7; 5 const ll mod = 1e9 + 7; 6 7 ll x[maxn], y[maxn], o1[maxn], o2[maxn]; 8 ll cul(ll index, pair<ll, pair<ll, ll>> culx){ 9 ll val; 10 if(culx.first == 0)val = x[index]; 11 else val = y[index]; 12 return val * culx.second.first + culx.second.second; 13 } 14 pair<ll, ll> ans[maxn]; 15 16 void print(pair<ll, pair<ll, ll>> p){ 17 cout << p.first << ' ' << p.second.first << ' ' << p.second.second << '\n'; 18 } 19 int main() 20 { 21 ll n, m, q; 22 cin >> n; 23 for(ll i = 1; i <= n; ++i)cin >> x[i] >> y[i]; 24 cin >> m; 25 for(ll i = 1; i <= m; ++i){ 26 cin >> o1[i]; 27 if(o1[i] >= 3) cin >> o2[i]; 28 } 29 cin >> q; 30 vector<pair<ll, pair<ll, ll> > > qp; 31 for(ll i = 0; i < q; ++i){ 32 ll a, b; 33 cin >> a >> b; 34 qp.push_back(make_pair(a, make_pair(b, i))); 35 } 36 sort(qp.begin(), qp.end()); 37 pair<ll, pair<ll, ll>> culx, culy; 38 culx = make_pair(0, make_pair(1, 0)); 39 culy = make_pair(1, make_pair(1, 0)); 40 ll index = 0; 41 for(ll i = 0; i <= m; ++i){ 42 //cout << "\n\ni = " << i << "\n"; 43 if(o1[i] == 1){ 44 swap(culx, culy); 45 culy.second.first *= -1; 46 culy.second.second *= -1; 47 } 48 else if (o1[i] == 2){ 49 swap(culx, culy); 50 culx.second.first *= -1; 51 culx.second.second *= -1; 52 } 53 else if(o1[i] == 3){ 54 culx.second.first *= -1; 55 culx.second.second = 2 * o2[i] - culx.second.second; 56 } 57 else if(o1[i] == 4){ 58 culy.second.first *= -1; 59 culy.second.second = 2 * o2[i] - culy.second.second; 60 } 61 else if(i == 0){ 62 63 } 64 else{ 65 assert(1 == 2); 66 } 67 //print(culx); 68 //print(culy); 69 //cout << "cul 1 culx " << cul(1, culx) << "\n"; 70 //cout << "cul 1 culy " << cul(1, culy) << "\n"; 71 while(index < q && qp[index].first == i){ 72 ans[qp[index].second.second].first = cul(qp[index].second.first, culx); 73 ans[qp[index].second.second].second = cul(qp[index].second.first, culy); 74 //int in = qp[index].second.second; 75 //cout << "in: " << in << ' ' << qp[index].second.first << ' ' << ans[in].first << ' ' << ans[in].second << '\n'; 76 //print(culx); 77 //print(culy); 78 index += 1; 79 } 80 } 81 for(int i = 0; i < q; ++i){ 82 cout << ans[i].first << ' ' << ans[i].second << '\n'; 83 } 84 85 return 0; 86 }
F、考虑维护pa数组,pa[i]代表从i->n需要走的步数的期望,则当i是K个坐标中的某一个时,pa[i] = pa[0],否则pa[i] = 1/m(pa[i + 1], pa[i + 2], pa[i + 3]... + pa[i + m]),全方程只有pa[0]一个未知数,解方程即可。
pa[i]的状态用(a, b)来表示,即,pa[i] = a * pa[0] + b
1 #include<iostream> 2 #include<set> 3 #include<cmath> 4 5 using namespace std; 6 7 const int maxn = 1e6 + 7; 8 pair<double, double> pa[maxn]; 9 int main() 10 { 11 int n, m, k; 12 cin >> n >> m >> k; 13 // cout << n << ' ' << m << ' ' << k << "\n"; 14 set<int> s; 15 for(int i = 0; i < k; ++i){ 16 int x; 17 cin >> x; 18 s.insert(x); 19 } 20 pa[n].first = pa[n].second = 0; 21 pair<double, double> p_cnt = make_pair(0, 0); 22 for(int i = n - 1; i >= 0; i--){ 23 p_cnt.first += pa[i + 1].first; 24 p_cnt.second += pa[i + 1].second; 25 p_cnt.first -= pa[min(n, i + m + 1)].first; 26 p_cnt.second -= pa[min(n, i + m + 1)].second; 27 if(s.count(i) > 0){ 28 pa[i].first = 1; 29 pa[i].second = 0; 30 } 31 else{ 32 pa[i].first = p_cnt.first * 1.0 / m; 33 pa[i].second = p_cnt.second * 1.0 / m + 1; 34 } 35 } 36 p_cnt = pa[0]; 37 if(fabs(p_cnt.first - 1.0) < 1e-12){ 38 cout << "-1\n"; 39 } 40 else{ 41 printf("%.4f\n", p_cnt.second * 1.0 / (1 - p_cnt.first)); 42 } 43 return 0; 44 }