2020/7/13 每日一题(构造)

Posted 钟钟终

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2020/7/13 每日一题(构造)相关的知识,希望对你有一定的参考价值。

每日一题是希望自己能认真的解析一道有价值的题,而非像之前一样写几句思路、放代码,希望能通过一道题能理解一类题的思路


F. Equate Multisets
难度:1700
题意:给定两个元素可重复的集合,集合B可通过将集合中元素乘以2或除以2(向下取整)来得到和集合A一样的集合。操作次数不限,输出YES或NO。
思路:初步判定是一个构造题,要用到数论知识,再开始思考。
首先看出无法排序,因为A、B两个集合中元素对应是没有规律的,因此转而去考虑数字的性质。
1.A中数字无法修改,A中奇数无法通过B中数字*2得到,只能通过/2得到;
2.A中偶数可有*2或者/2得到,致使B中数字选择和操作的不确定
3.A中偶数都可通过除以2来得到一个奇数,若B中数字可通过/2构造出与变型后都是奇数的A相同的集合,则满足题意。

此题关键:将A中数字都通过除以2构造成都为奇数的集合。
AC代码:转换了代码思路,用map,因为键可达1e9次方,用unordered_map()

#include<bits/stdc++.h>

using namespace std;
const int N=1e6+5;
unordered_map<int,int>mp;
int n,a[N],b[N];
bool flag;
int main()

    int t;cin>>t;
    while(t--)
    
        mp.clear();
        flag=0;
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        for(int i=1;i<=n;i++)
            cin>>b[i];
        for(int i=1;i<=n;i++)
        
            while(a[i]%2==0&&a[i])
                a[i]/=2;
            mp[a[i]]+=1;
        
        for(int i=1;i<=n;i++)
        
           while(b[i])
           
               if(b[i]%2&&mp[b[i]])
               
                   mp[b[i]]--;
                   break;
               
               else
                    b[i]/=2;
           
        
        for(int i=1;i<=n;i++)
            if(mp[a[i]])
            
                flag=1;break;
            
        if(flag)
            cout<<"NO"<<endl;
        else
            cout<<"YES"<<endl;
    


代码:(这份代码有点问题,思路一样,实现方式不同,找了好久,没找出来,在第7261组样例出了问题,看不了出错样例)

#include<bits/stdc++.h>

using namespace std;
const int N=1e6+5;
int n,a[N],b[N],c[N];
bool vis[N],flag;
int main()

    int t;cin>>t;
    while(t--)
    
        memset(vis,0,sizeof vis);
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        for(int i=1;i<=n;i++)
            cin>>b[i];
        for(int i=1;i<=n;i++)
        
            if(a[i]%2)
                c[i]=a[i];
            else
            
                c[i]=a[i];
                while(c[i]%2==0&&c[i]) c[i]/=2;
            
        
        sort(c+1,c+n+1);
        flag=0;
        for(int i=1;i<=n;i++)
        
            while(b[i])
            
                if(b[i]%2)
                
                    int k=lower_bound(c+1,c+n+1,b[i])-c;
                    while(vis[k])   k++;
                    if(!vis[k]&&b[i]==c[k])
                    
                        vis[k]=1;
                        break;
                    
                
                b[i]/=2;
            
            if(b[i]==0)
            
                flag=1;break;
            
        
        if(flag)
            cout<<"NO"<<endl;
        else
            cout<<"YES"<<endl;
    


以上是关于2020/7/13 每日一题(构造)的主要内容,如果未能解决你的问题,请参考以下文章

《LeetCode之每日一题》:245.超级次方

每日一题1331. 数组序号转换

java面试每日一题8

解题报告Leecode 372. 超级次方——Leecode每日一题系列

解题报告Leecode 372. 超级次方——Leecode每日一题系列

《LeetCode之每日一题》:46.4的幂