1176A. Divide it!

题目链接:http://codeforces.com/problemset/problem/1176/A

题意:

给定一个数字 Codeforces Round #565 (Div. 3) (重现赛个人题解) - 图1 和三种操作

  1. 如果 n 能被 2 整除则 Codeforces Round #565 (Div. 3) (重现赛个人题解) - 图2
  2. 如果 n 能被 3 整除 Codeforces Round #565 (Div. 3) (重现赛个人题解) - 图3
  3. 如果 n 能被 5 整除 Codeforces Round #565 (Div. 3) (重现赛个人题解) - 图4

求问 Codeforces Round #565 (Div. 3) (重现赛个人题解) - 图5 最少执行多少次能变成 Codeforces Round #565 (Div. 3) (重现赛个人题解) - 图6 ,如果不行则输出 Codeforces Round #565 (Div. 3) (重现赛个人题解) - 图7

  1. //搜索
  2. // Author : RioTian
  3. // Time : 20/10/15
  4. #include <bits/stdc++.h>
  5. using namespace std;
  6. typedef long long ll;
  7. ll _, n, cnt;
  8. void dfs(ll x, ll step) {
  9. if (x == 1) {
  10. cnt = min(step, cnt);
  11. return;
  12. }
  13. if (x % 2 == 0)
  14. dfs(x / 2, step + 1);
  15. else if (x % 3 == 0)
  16. dfs(x * 2 / 3, step + 1);
  17. else if (x % 5 == 0)
  18. dfs(x * 4 / 5, step + 1);
  19. else
  20. cnt = -1;
  21. }
  22. int main() {
  23. // freopen("in.txt", "r", stdin);
  24. ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  25. cin >> _;
  26. while (_--) {
  27. cin >> n, cnt = 9999999;
  28. if (n == 1)
  29. cnt = 0;
  30. else
  31. dfs(n, 0);
  32. cout << cnt << endl;
  33. }
  34. }
  1. //math
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. int64_t n, i, q;
  5. int main() {
  6. for (cin >> q; q--;) {
  7. cin >> n;
  8. for (i = 0; n > 1 && i < 200; i++)
  9. n % 2 == 0
  10. ? n /= 2
  11. : n % 3 == 0 ? n = 2 * n / 3 : n % 5 == 0 ? n = 4 * n / 5 : 0;
  12. cout << (n > 1 ? -1 : i) << endl;
  13. }
  14. }

1176B.Merge it!

题目链接:http://codeforces.com/problemset/problem/1176/B

Codeforces Round #565 (Div. 3) (重现赛个人题解) - 图8

题意:给定序列,任意俩个元素可以相加成一个元素,求序列元素能被3整除的最大数量。

思路: 对于所有元素进行 模3 的预处理,然后 贪心 余数1 和 余数2 的配对,剩下的 3个 一组配对。

AC代码:

  1. // Author : RioTian
  2. // Time : 20/10/15
  3. #include <bits/stdc++.h>
  4. using namespace std;
  5. typedef long long ll;
  6. int main() {
  7. // freopen("in.txt", "r", stdin);
  8. ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  9. int T;
  10. scanf("%d", &T);
  11. while (T--) {
  12. int n, t, a[3] = {0};
  13. scanf("%d", &n);
  14. for (int i = 0; i < n; i++) {
  15. scanf("%d", &t);
  16. a[t % 3]++;
  17. }
  18. printf("%d\n", a[0] + min(a[1], a[2]) +
  19. (max(a[1], a[2]) - min(a[1], a[2])) / 3);
  20. }
  21. }

1176C. Lose it!

题目链接:https://codeforces.com/problemset/problem/1176/C

题意:保证这个顺序 4,8,15,16,23,42 ,删除其他多余的数据,计算要删除多少个数字,才能保证剩下的数字能组成n套这样的(n≥1);

题解:遍历序列,如果这个数为n,且这个数前面的数字为1,则b[n++],b[前面那个数字]–。
例子:
12
4 8 4 15 16 8 23 15 16 42 23 42
遍历这个序列:
第一个数字是4,则b[4++];
第二个数字是8,则b[8++],b[4–];因为顺序是规定的,所以有8,一定有4。
第三个数字是4,则b[4++];
第四个数字是15,则b[15++],b[8–];
第五个数字是16,则b[16++],b[15–];如果有16一定有15,所以可以用16代替前面的所有数字。
以此类推。(建议在纸上画一下就可以理解了。)

  1. // Author : RioTian
  2. // Time : 20/10/15
  3. #include <bits/stdc++.h>
  4. #define ms(a, b) memset(a, b, sizeof a)
  5. using namespace std;
  6. typedef long long ll;
  7. const int N = 5e5 + 100;
  8. int n, m, a[N], ans[] = {4, 8, 15, 16, 23, 42}, vis[10];
  9. map<int, int> mp;
  10. void init() {
  11. mp[4] = 1; mp[8] = 2;
  12. mp[15] = 3; mp[16] = 4;
  13. mp[23] = 5; mp[42] = 6;
  14. ms(vis, 0);
  15. }
  16. int main() {
  17. //freopen("in.txt", "r", stdin);
  18. ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  19. while (cin >> n) {
  20. init();
  21. for (int i = 1; i <= n; i++) {
  22. cin >> m;
  23. if (mp[m] == 1)
  24. vis[1]++;
  25. else if (vis[mp[m] - 1] > 0) {
  26. vis[mp[m] - 1]--;
  27. vis[mp[m]]++;
  28. }
  29. }
  30. if (n < 6) cout << n << endl;
  31. else cout << n - vis[6] * 6 << endl;
  32. }
  33. return 0;
  34. }

1176D. Recover it!

https://codeforces.com/problemset/problem/1176/D

题意:给出b[n],按照一定的规则变成a[n];
题解:
原理是:倒推,原本题意是,由a[n]变成b[n];
遍历:
如果a[n]是质数,那么在b[n]中,保留a[n]并且加上质数表中的第a[n]个质数;
如果a[n]是合数,那么在b[n]中,保留a[n]并且加上b[n]的最大除数。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define N 3000000
  4. int n, i, j, k, x, p[N], q[N], c[N], b[N];
  5. int main() {
  6. for (i = 2; i < N; i++)
  7. if (!p[i]) {
  8. q[++k] = i;
  9. for (j = i + i; j < N; j += i) p[j] = 1;
  10. }
  11. for (cin >> n, i = 0; i < n + n;) cin >> b[i], c[b[i++]]++;
  12. sort(b, b + n + n);
  13. for (i = n + n - 1; i + 1; i--) {
  14. x = b[i];
  15. if (c[x] <= 0 || !p[x]) continue;
  16. for (j = 2; x % j; j++)
  17. ;
  18. cout << x << " ", c[x]--, c[x / j]--;
  19. }
  20. for (i = 0; i < n + n; i++)
  21. if (x = b[i], c[x] > 0) cout << x << " ", c[x]--, c[q[x]]--;
  22. return 0;
  23. }

1176E.Cover it! - bfs

https://codeforc.es/contest/1176/problem/E

https://www.cnblogs.com/Yinku/p/11217093.html

久了不写bfs了。一开始用dfs写,的确用dfs是很有问题的,一些奇怪的情况就会导致多染一些色。

注意无向图的边要开双倍。

  1. //DFS 修改以后AC的代码
  2. #include<bits/stdc++.h>
  3. const int maxn = 2e5+10;
  4. using namespace std;
  5. vector<int> V[maxn],ans[2];
  6. int n,m;
  7. int T;
  8. int vis[maxn];
  9. void dfs(int u,int ind) {
  10. vis[u]=1;
  11. ans[ind].push_back(u);
  12. for(auto nx:V[u]) {
  13. if(vis[nx]) continue;
  14. dfs(nx,ind^1);
  15. }
  16. return;
  17. }
  18. int main() {
  19. scanf("%d",&T);
  20. while(T--) {
  21. scanf("%d%d",&n,&m);
  22. for(int i=1;i<=n;++i) {V[i].clear();vis[i]=0;}
  23. ans[0].clear();ans[1].clear();
  24. for(int i=1;i<=m;++i) {
  25. int a,b;
  26. scanf("%d%d",&a,&b);
  27. V[a].push_back(b);
  28. V[b].push_back(a);
  29. }
  30. dfs(1,0);
  31. if(ans[0].size()>ans[1].size()) {
  32. swap(ans[0],ans[1]);
  33. }
  34. printf("%lu\n",ans[0].size());
  35. for(auto x:ans[0]) printf("%d ",x);
  36. puts("");
  37. }
  38. return 0;
  39. }