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 每日一题(构造)的主要内容,如果未能解决你的问题,请参考以下文章
解题报告Leecode 372. 超级次方——Leecode每日一题系列