A小亮的睡眠时间
思路:求一下一共花了多少时间思考,注意思考时间大于睡觉时间上限的特殊情况。
#include <iostream> using namespace std; int main() { int n; scanf("%d", &n); int sum = 0; int cur; int total = 450; int h = 0; int s = 0; for(int i = 0; i < n; i++) { scanf("%d", &cur); sum += cur; } sum = sum * 20; total = total - sum; if(total < 0) { total = 0; } h = total / 60; s = total % 60; printf("%02d:%02d\n", h, s); }
B 小亮是个大忙人
思路:考察阅读理解+前缀和差分
1. 题意写的很清楚,对于路程A到B(A<B),小亮要经过区间[A,B]中的所有站点,因此需要经过连接这些站点的路径,所以我们考虑用差分+前缀和统计每段路程的通过次数。
2. 还需要明确一点,那就是从A到B和从B到A,这两种情况是等价的,都会走过相同的路径,所以在计数的时候可以同质化处理,为了维护差分的左小右大性质,在差分统计路段次数的时候还需要让min(A,B)在左,max(A,B)在右。
3. 统计完路径次数以后,统计答案的时候,考虑对于通过k次的路段,是买k次不优惠的票还是买一个优惠卡然后买k次优惠的票合算即可。
4. 最大优惠其实就是统计总花费的时候,在所有最合算的路段花费中选择一个最大值输出。
#include <iostream> using namespace std; #define int long long const int N = 1e5 + 5; int p[N], a[N], b[N], c[N], s[N], n, S, m, l, r, res, maxv; signed main() { ios::sync_with_stdio(false), cin.tie(0); cin >> m >> n >> S; for (int i = 1; i <= n; i++) cin >> p[i]; for (int i = 2; i <= m; i++) cin >> a[i] >> b[i] >> c[i]; for (int i = 1; i < n; i++) { l = p[i], r = p[i + 1]; if (l > r) swap(l, r); s[l + 1]++, s[r + 1]--; } for (int i = 2; i <= m; i++) s[i] += s[i - 1]; for (int i = 2; i <= m; i++) res += min(s[i] * a[i], s[i] * b[i] + c[i]); for (int i = 2; i <= m; i++) maxv = max(maxv, min(s[i] * a[i], s[i] * b[i] + c[i])); if (res <= S) cout << res - maxv << endl << maxv << endl; else cout << "Infinity" << endl; }
C小亮圆皮:
思路:看似数据结构实则贪心
1. 对于长度为2的区间,一定有一个最大值一个最小值,此时我们获得有效值(max-min)。
2. 对于长度更大,包含长度为2的区间的区间,由于这个区间包含刚才的区间,因此区间内的max不会减少,而区间内的min不会增加,二者差值不会变得更小。
3. 因此,只需在所有区间长度为2的区间里取一个最小差值即可。
#include <iostream> using namespace std; const int N = 1e5 + 5; int n, a[N], res = 0x3f3f3f3f; int main() { ios::sync_with_stdio(false), cin.tie(0); cin >> n; for (int i = 1; i <= n; i++) cin >> a[i]; for (int i = 1; i < n; i++) res = min(res, abs(a[i] - a[i + 1])); cout << res << endl; }
D小亮想零元购:
思路:一道分类讨论的贪心
1. 我们把所需凑出的价格分为需要多少k元货币rk和需要多少1元货币r1。
2. 如果我们手里的k元货币ak足够,则答案为max(0,r1-a1),剩下的一元货币有多少用多少,多退少补即可。
3. 如果我们手里的k元货币ak不够凑出rk个,那也先把ak个k元货币用了,得到rk=rk-ak为还需凑出的k元货币个数。
(1)接下来讨论1元货币,如果已有的1元货币多余所需1元货币,则有a1>r1,我们先把这些1元货币用了,然后剩下多少就去凑k元货币。由于k元货币的价格和1元货币都一样,都算一张货币,因此如果我们的1元货币不够凑出完整的k元货币,那还不如直接买一张k元货币,因此这种情况下的答案是max(0, rk - a1 / k)。
(2)如果手里的1元货币不足以支撑所需,那么差多少张1元买多少张一元,差多少张k元,买多少张k元,答案为 (r1 - a1) + rk。
#include <iostream> using namespace std; int t, m, k, r1, rk, a1, ak; int main() { ios::sync_with_stdio(false), cin.tie(0); cin >> t; while (t--) { cin >> m >> k >> a1 >> ak, r1 = m % k, rk = m / k; if (ak > rk) cout << max(0, r1 - a1) << "\n"; else { rk -= ak; if (a1 > r1) a1 -= r1, cout << max(0, rk - a1 / k) << "\n"; else cout << (r1 - a1) + rk << "\n"; } } }
E. 小亮带发明家
思路:性质题,跟我讲的硬币翻转很像。
1. 首先考虑一个显然的性质,那就是翻转硬币不可能超过一次。
2. 题目要求我们每次翻转都是从头开始翻任意个,那么考虑一个O(N)的策略:用flag记录当前已经确定的前k个煎饼的状态(初始为第一个煎饼的状态),然后查看第k+1个煎饼的状态,如果跟flag一致,则前k+1个煎饼的状态仍为flag;如果第k+1个煎饼的状态跟flag不同,则把前k个煎饼全翻面并更改flag,我们仍然获得了前k+1个煎饼的状态。
3. 如此,可O(N)计算答案,每次更改flag对应了一次翻面,答案为flag更改的次数。注意,最后题目要求所有煎饼正面朝上,因此如果最终前n个煎饼的flag为0,还需全部翻面,次数加1。
#include <iostream> #include <string> using namespace std; string s; char flag; int res; int main() { cin >> s, flag = s[0]; for (int i = 1; i < s.size(); i++) if (flag != s[i]) flag = s[i], res++; if (flag != '1') res++; cout << res << endl; }
F.小亮xor小亮
思路:首先你要知道异或有个性质,那就是自己异或自己得0。
1. 根据题意,可以得知:b异或一遍等价于把(a异或一遍)xor(x异或n次),我们想让这个数为0。
2. 我们令a数组异或的最终值为ans。
3. 所以当n为偶数的时候,x总是两两相消,所以当ans本身就为0的时候,x是谁都可以(值域内任何一个数)题目要求输出最小的,那就输出0,当ans本身不为0的时候,x是谁都不行(输出-1)。
4. 当n位奇数的时候,x会余下来一个,则x xor ans = 0,那么x就等于ans。
#include <bits/stdc++.h> using namespace std; int main() { ios; int t; cin >> t; while (t--) { int n; cin >> n; int ans; cin >> ans; for (int i = 1; i <= n - 1; i++) { int x; cin >> x; ans ^= x; } if (n & 1) { cout << ans << endl; } else { if (ans == 0) cout << 0 << endl; else cout << -1 << endl; } } return 0; }
G.彬彬有礼的小亮
思路:类似新生赛的那道“说的道理”。
1. 从头开始扫一遍,每个位置的找一下子串是否符合目标子串,不符合就往下走看下一个位置,如果符合,就让下标直接跳过子串长度,去看后面的位置,
#include <iostream> #include <string> using namespace std; int main(){ string s,t; cin >> s >> t; int ans = 0; for(int i = 0;i < s.size();i ++){ if(t[0] == s[i]){ bool flag = 1; for(int j = 0;j < t.size();j ++){ if(t[j] != s[i+j]) { flag = 0; break; } } if(flag){ ans ++; i += t.size()-1; } } } cout << ans << endl; }
H. 小亮学图像处理
思路:直接预处理出来一个足够长的字母串,然后根据题意模拟即可,注意细节,多调几次就过了,看代码即可。
#include <iostream> #include <string> using namespace std; int main(){ string tmp = "abcdefghijklmnopqrstuvwxyz"; string str = ""; for(int i = 1;i <= 10;i ++){ str += tmp; } int n; cin >> n; for(int i = 0;i < n/2+1 ;i ++){ for(int j = 0;j < n/2+1 ;j ++){ cout<<str[j + i]; } for(int j = n/2-1;j >= 0;j --){ cout<<str[j + i]; } cout<<endl; } for(int i = n/2-1;i >=0;i --){ for(int j = 0;j < n/2+1 ;j ++){ cout<<str[j + i]; } for(int j = n/2-1;j >= 0;j --){ cout<<str[j + i]; } cout<<endl; } }
I. 骰子大师小亮:
思路:各个骰子之间是独立的,只需模拟即可,开一个数组记录输入的序列,然后开另一个数组初始化全为7,然后开始模拟扔骰子,每次让这些数组往下减一,如果减完以后的数和输入的序列一致,那就再减一。
#include <iostream> using namespace std; int b[7] = {7, 7, 7, 7, 7, 7, 7}, a[7], n; int main() { for (int i = 1; i <= 6; i++) cin >> a[i]; cin >> n; while (n--) { for (int i = 1; i <= 6; i++) { b[i]--; if (b[i] == a[i]) b[i]--; } } for (int i = 1; i <= 6; i++) cout << b[i] << " "; cout << endl; }
J. 小亮被网络诈骗
思路:用map记录字母出现个数,然后看看map存了多少个字母(size)即可。
#include <bits/stdc++.h> using namespace std; int main() { map<char, int> m; string str; cin >> str; int sum = 0; for (int i = 0; i < str.size(); i++) { if (m[str[i]] == 0) { m[str[i]]++; sum++; } } if (sum % 2 == 0) { printf("CHAT WITH HER!\n"); } else { printf("IGNORE HIM!\n"); } return 0; }
K. 小亮的Team:
思路:每个题是否编写解决方案是独立的,只需看三个人的数字加起来是否大于1即可。
#include <bits/stdc++.h> using namespace std; int main() { int n; cin >> n; int sum = 0; for (int i = 0; i < n; i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); if (a + b + c >= 2) { sum++; } } printf("%d", sum); return 0;标签:小亮,int,题解,新生,cin,++,flag,理工,include From: https://www.cnblogs.com/BIOS0408/p/17810458.html