Codeforces Round \#479 (Div. 3)(题解)

分手后的思念是犯贱 2022-05-24 10:14 284阅读 0赞

A. Wrong Subtraction

**题意:给出一个数字n,然后进行k次操作,每次在n的个位上减1,如果个位是0的话,去掉这一位,继续操作,输出最后结果

思路:模拟减1操作,直接用个位数字与k比较,如果n大,那么输出n-k,否则需要判断是否能把个位去掉**

  1. #include<iostream>
  2. #include<cstdio>
  3. using namespace std;
  4. typedef long long ll;
  5. int main() {
  6. ll n, k;
  7. int ans = -1;
  8. scanf("%lld %lld", &n, &k);
  9. while(k > 0) {
  10. int x = n % 10;
  11. if(x > k) {
  12. ans = n - k;
  13. k = 0;
  14. }else {
  15. if(x == k) {
  16. ans = n - x;
  17. k = 0;
  18. }else {
  19. k = k - x - 1;
  20. n /= 10;
  21. ans = n;
  22. }
  23. }
  24. }
  25. printf("%d\n", ans);
  26. return 0;
  27. }

B. Two-gram

**题意:给出一字符串,找出其中出现最多的两个相邻的字母

思路:用string枚举所有的可能,循环判断次数**

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<map>
  5. using namespace std;
  6. typedef long long ll;
  7. map<string, int> mp;
  8. int main() {
  9. int n, maxx = -1;
  10. cin >> n;
  11. string s, ans, p;
  12. cin >> s;
  13. for(int i = 0; i < n-1; i++) {
  14. p = s.substr(i,2);
  15. mp[p]++;
  16. if(mp[p] > maxx) {
  17. maxx = mp[p];
  18. ans = p;
  19. }
  20. }
  21. cout << ans << endl;
  22. return 0;
  23. }

C. Less or Equal

**题意:给出n,k和一组数字(无大小顺序),从n个数中找出k个数字,输出一个x,x是大于等于k个数字中最大的,如果没有输出-1

思路:首先排序,因为要找k个数字,查看第k个数字是否跟k+1一样大,如果一样大就找不出k个(至少k+1个)
还有一个问题,当k为0的情况,因为$1<=a_{i}<=10^{9}$是从1开始的,当k=0时,要找出0个,如果排完续后$a_{1}=1的话,就不可能找出x,输出-1
否则输出1**

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<map>
  6. using namespace std;
  7. typedef long long ll;
  8. const ll maxn = 1e6+5;
  9. ll a[maxn];
  10. int main() {
  11. int n, m;
  12. scanf("%d %d", &n, &m);
  13. for(int i = 0; i < n; i++) {
  14. scanf("%I64d", &a[i]);
  15. }
  16. sort(a,a+n);
  17. if(n == m) {
  18. printf("%I64d", a[m-1]);
  19. return 0;
  20. }
  21. if(m == 0) {
  22. if(a[0] == 1) printf("-1\n");
  23. else printf("1\n");
  24. }else {
  25. if(a[m] == a[m-1]) printf("-1\n");
  26. else printf("%I64d\n", a[m-1]);
  27. }
  28. return 0;
  29. }

D. Divide by three, multiply by two

**题意:给出一组数字,按照要求排序,规则是后面的数只能由前面的数÷3或者×2得来,题目一定可解

思路:根据一个排序规则排序即可,根据每个数字对3能取余的次数,从大到小排序,如果一样的话,再根据剩下数字的从小到大排序 原因:要把能把3除尽的大的数字尽可能放前面,使他们变小,除了能÷3的数字,就是偶数,需要从小到大排,因为×会变大**

  1. #include<iostream>
  2. #include<vector>
  3. #include<cstring>
  4. #include<algorithm>
  5. #define INIT ios::sync_with_stdio(false)
  6. using namespace std;
  7. typedef long long ll;
  8. const int maxn = 105;
  9. ll a[maxn];
  10. vector<ll> v;
  11. bool cmp(ll a, ll b) {
  12. int numa = 0, numb = 0;
  13. while (a % 3 == 0) {
  14. a /= 3;
  15. numa++;
  16. }
  17. while (b % 3 == 0) {
  18. b /= 3;
  19. numb++;
  20. }
  21. if (numb != numa) return numa > numb;
  22. return a < b;
  23. }
  24. int main() {
  25. INIT;
  26. int n;
  27. ll x;
  28. cin >> n;
  29. for (int i = 0; i < n; i++) {
  30. cin >> x;
  31. v.push_back(x);
  32. }
  33. sort(v.begin(), v.end(), cmp);
  34. for (int i = 0; i < n - 1; i++) {
  35. cout << v[i] << " ";
  36. }
  37. cout << v[n - 1] << endl;
  38. return 0;
  39. }

E. Cyclic Components

**题意:给出一个图,找出图中有多少个环,都是单环,没有多余的边

思路:利用链表存储,存储两个方向,根据一个点开始搜索,变搜索边标记,如果每一个点可以连接另外两个点(一个进一个出),那么是符合要求的,如果不是,要么不是环,要么是一个复杂环**

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include <map>
  5. using namespace std;
  6. const int maxn = 2e5+10;
  7. vector <int> v[maxn];
  8. bool vis[maxn];
  9. int flag;
  10. void dfs(int x) {
  11. vis[x] = true;
  12. if(v[x].size() != 2) flag = 1;
  13. for(int i : v[x]) {
  14. if(!vis[i])
  15. dfs(i);
  16. }
  17. }
  18. int main() {
  19. int n, m, ans = 0;
  20. cin >> n >> m;
  21. for(int i = 1; i <= m; i++) {
  22. int x, y;
  23. cin >> x >> y;
  24. v[x].push_back(y);
  25. v[y].push_back(x);
  26. }
  27. memset(vis, false, sizeof(vis));
  28. for(int i = 1; i <= n; i++) {
  29. flag = 0;
  30. if(!vis[i]) {
  31. dfs(i);
  32. if(!flag) ans++;
  33. }
  34. }
  35. cout << ans << endl;
  36. return 0;
  37. }

F. Consecutive Subsequence

**题意:给出一组数字,输出其中一组数的坐标,要求是找出最长的上升序列,每次递增1

思路:用map记录一个数字前面连续数字的个数,中间记录最长的长度,和坐标,最后根据最后的数字跟长度可以推算出开始的数字,循环输出即可**

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include <map>
  5. using namespace std;
  6. typedef long long ll;
  7. const int maxn = 2e5+10;
  8. int a[maxn];
  9. map<int ,int > mp;
  10. int main() {
  11. int n, ans, len = -1;
  12. cin >> n;
  13. for(int i = 1; i <= n; i++) {
  14. cin >> a[i];
  15. int x = a[i];
  16. mp[x] = mp[x-1] + 1;
  17. if(len < mp[x]) {
  18. len = mp[x];
  19. ans = x;
  20. }
  21. }
  22. cout << len << endl;
  23. int startNum = ans - len + 1;
  24. for(int i = 1; i <= n; i++) {
  25. if(a[i] == startNum) {
  26. cout << i << " ";
  27. startNum++;
  28. }
  29. }
  30. cout << endl;
  31. return 0;
  32. }

发表评论

表情:
评论列表 (有 0 条评论,284人围观)

还没有评论,来说两句吧...

相关阅读