做题一时爽,补题...
2042. 检查句子中的数字是否递增
签到题
class Solution: mymax = -1 def areNumbersAscending(self, s: str) -> bool: x_list = s.split() for x in x_list: if x[0].isdigit() : num = eval(x) if num <= self.mymax : return False else: self.mymax = num return True
2043. 简易银行系统
模拟题,注意账户不存在的情况
class Bank { public: long long vec[100000+10]; int len; Bank(vector<long long>& balance) { len = balance.size(); for(int i = 0;i < balance.size();i++) vec[i+1] = balance[i]; } bool isPre(int account) { if(account >=1 && account <= len) return true; return false; } bool transfer(int account1, int account2, long long money) { if(isPre(account1) == false || isPre(account2) == false) return false; if(vec[account1] < money) return false; vec[account1] -= money; vec[account2] += money; return true; } bool deposit(int account, long long money) { if(isPre(account) == false) return false; vec[account] += money; return true; } bool withdraw(int account, long long money) { if(isPre(account) == false) return false; if(vec[account] < money) return false; vec[account] -= money; return true; } }; /** * Your Bank object will be instantiated and called as such: * Bank* obj = new Bank(balance); * bool param_1 = obj->transfer(account1,account2,money); * bool param_2 = obj->deposit(account,money); * bool param_3 = obj->withdraw(account,money); */
2044. 统计按位或能得到最大值的子集数目
按位或的最大值就是全部或进来,然后在二进制枚举
class Solution { public: int cal(vector<int>& nums) { int res = 0; for(int num : nums) res |= num; return res; } int countMaxOrSubsets(vector<int>& nums) { int mymax = cal(nums); // cout << mymax << endl; int n = nums.size(); int res = 0; for(int i = 0;i < (1<<n);i++) { int tmp = 0; for(int j = 0; j < n;j++) { if(i&(1<<j)) tmp |= nums[j]; } if(tmp == mymax) res++; } return res; } };
2045. 到达目的地的第二短时间
其实只需要跳数就能求出所用时间,所以用BFS求出次短路即可
class Solution { public: int secondMinimum(int n, vector<vector<int>>& edges, int time, int change) { unordered_map<int, vector<int>>mp(n); for(auto edge : edges) { int u = edge[0], v = edge[1]; // cout << u << " " << v << endl; mp[u].push_back(v); mp[v].push_back(u); } vector<int>dis(n+1); // 到1的距离 queue<int>q; while(!q.empty()) q.pop(); dis[1] = 0; q.push(1); while(!q.empty()){ int u = q.front(); q.pop(); // cout << "u: " << u << endl; if(u == n) break; for(int v : mp[u]){ // cout << "v: " << v << endl; if(dis[v] == 0 && (v!=1)) { dis[v] = dis[u]+1; q.push(v); } } } // cout << "******" << endl; while(!q.empty()) q.pop(); q.push(n); int res = dis[n]; bool flag = false; while(!q.empty()){ int sz = q.size(); for(int i = 0;i < sz;i++) { int u = q.front(); // cout << "u: " << u << endl; q.pop(); for(int v : mp[u]){ // cout << "v: " << v << endl; if(dis[v] == res) {flag = true; break;} if(dis[v] == res-1) q.push(v); } } if(flag) break; res--; } // for(int i = 1;i <= n;i++) cout << dis[i] << endl; int times = flag ? dis[n]+1 : dis[n]+2; // cout << "times: " << times << endl; int t = 0; // 当前时间 while(times--) { t += time; if(times==0) break; // 最后一次了就不需要等了 int tmp = t/change; if(tmp%2) { // 奇数,不用等 t = (tmp+1)*change; } // cout << "t: " << t << endl; } return t; } };
Codeforces Round #749 (Div. 1 + Div. 2, based on Technocup 2022 Elimination Round 1)
A. Windblume Ode
题意:求最大的子集数,使得子集和为和数,n>=3且每个数互异
思路:先求全部元素之和,如果是合数即为答案;如果不是,则是质数,质数一定是奇数,而n个数中一定存在奇数,所以答案是n-1
#include<cstdio> #include<iostream> using namespace std; int n; int a[105]; bool isPrime(int num) { for(int i = 2;i*i <= num;i++) { if(num % i == 0) return false; } return n!=1; } int main() { int T; scanf("%d", &T); while (T--) { scanf("%d", &n); int sum = 0; for(int i = 0;i < n;i++) { scanf("%d", &a[i]); sum += a[i]; } if(!isPrime(sum)) { printf("%d ", n); for(int i = 0;i < n;i++) printf("%d%c", i+1, i == n-1? ' ' : ' '); } else { printf("%d ", n-1); int flag = true; for(int i = 0;i < n;i++) { if((a[i]%2) && flag) flag=false; else printf("%d ", i+1); // printf("%c", i==n-1?' ':' '); } printf(" "); } } }
B. Omkar and Heavenly Tree
题意:有m条限制a b c(意思是b不能位于a到c的最短路径上),构造一个满足所有限制的n个节点的树,m<n
思路:因为m<n,则至少存在一个节点不受限制,把它作为中心,构造一个星型图
#include<cstdio> #include<cstring> #include<iostream> using namespace std; int n, m; const int maxn = 100000+10; bool vis[maxn]; int main(){ int T; scanf("%d", &T); while (T--) { scanf("%d%d", &n, &m); memset(vis, 0, sizeof(vis)); int a, b, c; for(int i = 0;i < m;i++) { scanf("%d%d%d", &a, &b, &c); vis[b] = true; } int center; for(int i = 1;i <= n;i++){ if(!vis[i]) { center = i; break; } } for(int i = 1;i <= n;i++) { if(i != center) printf("%d %d ", i, center); } } return 0; }
C. Omkar and Determination
题意:有点绕,给定一个地图,只能走空格和往上往左走,如果从该格出发能走出去称为exitable,如果给定每个格子的exitable情况,能反推原地图,则称为determinable。现有q次查询, 询问x1~x2列组成的网格是否是可determinable的
思路:
只要存在
*
* _
这个结构就不是determinable,如果没有这个结构,就一定可以反推回去。自己想想这个结论
#include<cstdio> #include<cstring> #include<iostream> #include<string> #include<vector> using namespace std; int n, m; const int maxn = 1e6+10; int cols[maxn]; vector<string>maze; int main(){ ios::sync_with_stdio(false); cin >> n >> m; maze.resize(n); for(int i = 0;i < n;i++) cin >> maze[i]; for(int i = 1;i < n;i++) for(int j = 1;j < m;j++) { if(maze[i-1][j] == 'X' && maze[i][j-1] == 'X') cols[j]++; } for(int i = 1;i <= m;i++) cols[i] += cols[i-1]; int q, a, b; cin >> q; while (q--) { cin >> a >> b; a--, b--; if(cols[b]-cols[a]) cout << "NO "; else cout << "YES "; } return 0; }
D, E,F,G,H,I 补不动了,短期目标是稳定前3道
cf题解都是参考的赛后官方教程