题目链接:codeforces 1234A
题意:
一家商店有n个物品,价格分别为a[i] ,店员为了省事,所以打算把所有商品价格调成相同的,但不能亏损,也不能谋暴利,求最小的可行答案
解题思路:
........
#include <bits/stdc++.h> using namespace std; int main(){ int q; cin >> q; while(q--){ int n, sum = 0; cin >> n; for(int i = 1; i <= n; i++){ int u; cin >> u; sum += u; } if(sum % n == 0){ cout << sum / n << endl; } else{ cout << sum / n + 1 << endl; } } return 0; }题目链接:codeforces 1234 B1
题意:
有一个智能机,有n条信息,屏幕只能放下k条信息 (1 ≤ n,k ≤ 200) ,每次新来的消息总会置顶,相同的消息位置会不变,超出屏幕的消息会被挤掉,问最终屏幕上的消息数量和从顶到底的消息顺序
解题思路:
由于n和k很小,所以模拟就好,我用数组模拟队列
#include <bits/stdc++.h> using namespace std; int main(){ int n, k, l = 0; cin >> n >> k; int a[500]; int ans = 0; for(int i = 1; i <= n; i++){ int u; cin >> u; if(ans == 0){ ans++; a[ans] = u; } else{ int f = 0; for(int j = l+1; j <= ans; j++){ if(a[j] == u){ f = 1; break; } } if(f == 0){ ans++; a[ans] = u; if(ans-l > k){ l++; } } } } cout << ans - l << endl; for(int j = ans; j > l; j--){ cout << a[j] << " " ; } return 0; }题目链接:codeforces 1234 B2
题意:
同上 n 和 k 的范围变化 , (1 ≤ n, k ≤ 2⋅10^5 )
解题思路:
此时如果模拟会超出时间,所以要用数据结构简化查询的时间, 不能像上面的操作一步一步查,用一个 set记录此元素是否在队列中(官方说set的查询时间复杂度很低) 具体见 codeforces关于set链接
#include <bits/stdc++.h> using namespace std; int main(){ int n, k; cin >> n >> k; queue<int> q; set<int> s; for(int i = 1; i <= n; i++){ int id; cin >> id; if(!s.count(id)){ // 元素此时是否在set中 if(q.size() >= k){ // 屏幕中元素是否达到上限 int cur = q.front(); q.pop(); // pop出 s.erase(cur); // set中也删除 } q.push(id); // 推入新元素 s.insert(id); } } int m = q.size(); cout << q.size() << endl; vector<int> v; while(!q.empty()){ v.push_back(q.front()); q.pop(); } reverse(v.begin(), v.end()); // 反向输出 for(int i = 0; i < m; i++){ cout << v[i] << " "; } return 0; }题目链接:codeforces 1234C
题意:
有6种管子,分布在两行,管子可以旋转,问水是否能从管子的左上角流通出右下角
管子如图所示
管子中的水流通方式
解题思路:
可以先分析管子,1和2是相同的可以通过旋转得到,3,4,5,6都可以通过旋转相互得到,所以只有两种管子
分析路线图,因为只有两行,所以1号管子用不着,只能用2号管子进行左右流通,还可以看出只要从入口出发,碰到3,4,5,6号管子必拐弯,但如果上面的管子往下拐弯后碰到1号或2号管子必不可能进行下一步的流通,下面的管子同理,但是往右碰到1号或2号管子是没有问题的。分析结束
#include <bits/stdc++.h> using namespace std; const int maxn = 2e5+5; int a[maxn]; int main(){ int q; cin >> q; while(q--){ int n, i = 0, j; cin >> n; string s[5]; cin >> s[0] >> s[1]; for(j = 0; j < n; j++){ if(s[i][j] > '2'){ if(i == 0){ if(s[1][j] < '3'){ break; } else{ i = 1; } } else{ if(s[0][j] < '3'){ break; } else{ i = 0; } } } } if(i == 1 && j == n){ cout << "YES" << endl; } else{ cout << "NO" << endl; } } return 0; }题目链接:codeforces 1234D
题意:
给一个字符串,然后进行m次操作,分别有两种操作
1. 将x位置的字符变成 c
2. 输出 L 到 R之间字符不相同的个数
解题思路:
用set存储每个字符的下标,然后替换操作用erase 进行删除,insert进行插入,Lower_bounder进行查询
#include <bits/stdc++.h> using namespace std; set<int> se[30]; set<int>::iterator it; string s; int main(){ cin >> s; int n = s.size(); for(int i = 0; i < n; i++){ se[s[i]-'a'].insert(i+1); } int m; cin >> m; for(int i = 1; i <= m; i++){ int k; cin >> k; if(k == 1){ int pos; char c; scanf("%d %c", &pos, &c); se[s[pos-1] -'a'].erase(pos); s[pos-1] = c; se[c-'a'].insert(pos); //cout << s <<endl; } else{ int l, r, ans = 0; cin >> l >> r; for(int j = 0; j < 26; j++){ it = se[j].lower_bound(l); if(it == se[j].end()){ continue; } if((*it) <= r){ ans++; //cout << (*it) << " * " << r << endl; } } printf("%d\n", ans); } } return 0; }