2019/12/15 CF-1277-B Make Them Odd

Codeforces Round #606 (Div. 2, based on Technocup 2020 Elimination Round 4)

题目链接:http://codeforces.com/contest/1277/problem/B

测试样例:

input
4
6
40 6 40 3 20 1
1
1024
4
2 4 8 16
3
3 1 7

output
4
10
4
0

Note

In the first test case of the example, the optimal sequence of moves can be as follows:

  • before making moves a=[40,6,40,3,20,1]a=[40,6,40,3,20,1];
  • choose c=6c=6;
  • now a=[40,3,40,3,20,1]a=[40,3,40,3,20,1];
  • choose c=40c=40;
  • now a=[20,3,20,3,20,1]a=[20,3,20,3,20,1];
  • choose c=20c=20;
  • now a=[10,3,10,3,10,1]a=[10,3,10,3,10,1];
  • choose c=10c=10;
  • now a=[5,3,5,3,5,1]a=[5,3,5,3,5,1] — all numbers are odd.

Thus, all numbers became odd after 44 moves. In 33 or fewer moves, you cannot make them all odd.

题目大意:

        每次选择一个偶数变为奇数,最终将所有数字全部变为奇数,寻找最小变换次数。变换规则为将偶数除以2,可将其等大小的同时变换。

思路:

        为了寻找最小变换次数,理论上从最大的偶数开始做除以2变换,直到变为奇数或者是出现过的数字。变为出现过的就停止变换,则是可以留着后面一起变换,减少变换次数。代码方面则可以从小到大遍历,当大的变为出现过的时,可认为不需要再次变换了。

AC代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        int cnt=0;
        map<int,int> mp;
        for(int i=0;i<n;i++)
        {
            int x;
            scanf("%d",&x);
            mp[x]++;
        }
        for(map<int,int>::iterator it=mp.begin();it!=mp.end();it++)
        {
            if(it->second&&it->first%2==0)
            {
                int num=it->first;
                while(num&&num%2==0)
                {
                    num>>=1;
                    cnt++;
                    if(mp[num])
                        break;
                }
            }
        }
        printf("%d\n",cnt);
    }
    return 0;

}

解题过程:

        开始使用数组标记数字,当输入数字n,a[n]++,表示n出现过。但这样数组会越界,因为数字范围超出了数组范围,也开不了数字最大值大小的数组。

        然后开始尝试用map来标记,发现用不来迭代器,跑去查迭代器用法。。。。。。

发布了26 篇原创文章 · 获赞 1 · 访问量 430

猜你喜欢

转载自blog.csdn.net/qq_45309822/article/details/103544867
今日推荐