Codeforces Round #565 (Div. 3) ( A B C)解题报告

你的名字 2022-01-20 11:29 281阅读 0赞

A. Divide it!

题意:给你一个n,如果n可以被2整除,乘上1/2; 如果n可以被3整除,乘上2/3;如果n可以被5整除,乘上4/5; 问最小多少步处理n可以到1。

思路:
首先判断n可不可以变成1,然后从减少最多的开始操作,直到n=1结束。

AC代码:

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cmath>
  4. #include<map>
  5. #include<cstring>
  6. using namespace std;
  7. typedef long long ll;
  8. const int mmax=1e6+10;
  9. const int eps=1e-8;
  10. int main()
  11. {
  12. ios::sync_with_stdio(false);
  13. ll n;
  14. cin>>n;
  15. while(n--)
  16. {
  17. ll a;
  18. cin>>a;
  19. ll ans=a;
  20. ll num1;
  21. while(ans%2==0)
  22. ans/=2;
  23. while(ans%3==0)
  24. ans/=3;
  25. while(ans%5==0)
  26. ans/=5;
  27. //cout<<ans<<endl;
  28. if(a==1)
  29. cout<<"0"<<endl;
  30. else if(ans>1)
  31. cout<<"-1"<<endl;
  32. else
  33. {
  34. ll sum=0;
  35. for(int i=1;i<10000000000;i++)
  36. {
  37. if(a%2==0)
  38. {
  39. sum++;
  40. a=a/2;
  41. }
  42. else if(a%3==0)
  43. {
  44. sum++;
  45. a=a/3*2;
  46. }
  47. else if(a%5==0)
  48. {
  49. sum++;
  50. a=a/5*4;
  51. }
  52. if(a==1)
  53. break;
  54. }
  55. cout<<sum<<endl;
  56. }
  57. }
  58. return 0;
  59. }

B. Merge it!~

题意:给你有一个数列,可以合并任意两个,问你最后有多少个数可以被3整除。

思路:输入的时候先把3的倍数找出来,然后遍历一边数组,统计一下所有数对3取余的个数为 也就是取余完1的个数,2的个数,0的个数,只需考虑1和2的个数,3是1+2得来的所以去min(1的个数,2的个数),然后3还可以被3个1和3个2得来,再用剩下1和2的个数除以3,所有的加起来就是答案。

AC代码:

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cmath>
  4. #include<map>
  5. #include<cstring>
  6. using namespace std;
  7. typedef long long ll;
  8. const int mmax=1e6+10;
  9. const int eps=1e-8;
  10. ll a[mmax],book[mmax];
  11. int main()
  12. {
  13. ios::sync_with_stdio(false);
  14. ll t;
  15. cin>>t;
  16. while(t--)
  17. {
  18. memset(book,0,sizeof(book));
  19. ll n;
  20. cin>>n;
  21. ll sum=0;
  22. for(int i=0;i<n;i++)
  23. {
  24. cin>>a[i];
  25. if(a[i]%3==0)
  26. sum++;
  27. }
  28. for(int i=0;i<n;i++)
  29. {
  30. book[a[i]%3]++;
  31. }
  32. ll ans=min(book[1],book[2]);
  33. book[1]-=ans;
  34. book[2]-=ans;
  35. ll ans1=book[1]/3;
  36. ll ans2=book[2]/3;
  37. cout<<sum+ans+ans1+ans2<<endl;
  38. }
  39. return 0;
  40. }

C. Lose it!~

题意:有一个完美数组 4 8 15 16 23 42 ,任意给你一个数组,问删除多少个才是完美数组(符合完美数组的条件我就不说了,题目里有)。

思路: (greedy)
其实就是问你数组里最多有多少个完美数组(完美数组的个数和顺序不能颠倒),
最后用数组长度 - 完美数组的个数*6 就是答案。
首先怎么看4 8 15 16 23 42 的顺序的,想一个,每个数参照前一个数永远是最优的(我自己总结的),第一个4不用看,8是根据4的,15是根据8的…,for循环遍历一边数组,如果是4,4的个数增加1,如果是8,看8的个数是不是小于4,如果是,说明8正好可以用一个4来构成一个完美数组,如果不是,说明前面没有4来跟8构成完美数组的前两位,以此类推,一直遍历到最后,最后42的个数就是整个数组里面完美数组的个数。

AC代码:

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cmath>
  4. #include<map>
  5. #include<cstring>
  6. using namespace std;
  7. typedef long long ll;
  8. const int mmax=1e6+10;
  9. const int eps=1e-8;
  10. ll a[mmax],book[mmax];
  11. int main()
  12. {
  13. ios::sync_with_stdio(false);
  14. ll n;
  15. while(cin>>n)
  16. {
  17. memset(book,0,sizeof(book));
  18. for(int i=1;i<=n;i++)
  19. {
  20. cin>>a[i];
  21. }
  22. for(int i=1;i<=n;i++)
  23. {
  24. if(a[i]==4)
  25. book[4]++;
  26. else if(a[i]==8)
  27. {
  28. if(book[8]<book[4])
  29. book[8]++;
  30. }
  31. else if(a[i]==15)
  32. {
  33. if(book[15]<book[8])
  34. book[15]++;
  35. }
  36. else if(a[i]==16)
  37. {
  38. if(book[16]<book[15])
  39. book[16]++;
  40. }
  41. else if(a[i]==23)
  42. {
  43. if(book[23]<book[16])
  44. book[23]++;
  45. }
  46. else if(a[i]==42)
  47. {
  48. if(book[42]<book[23])
  49. book[42]++;
  50. }
  51. }
  52. cout<<n-book[42]*6<<endl;
  53. }
  54. return 0;
  55. }

发表评论

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

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

相关阅读