https://codeforces.com/problemset/problem/1221/A
这场掉一波大分,ABCD都用了巨复杂的方法做,其实都有更简单的做法,而且C还一直不知道错哪了,导致罚时爆炸
A题我没看到每个数字都是2的平方,然后看到2^29我不知道怎么脑抽觉得是long long
看了2分钟就过的代码,直接把<=2048的数字加起来如果大于2048就是YES,因为如果只有1个,就无法合并,此时没超过2048就说明是无法合并的情况或者合并的情况够不着2048,因为1+2+4...+1024全部都只有一个,也只有2047,所以必须满足某一个数字有多个,然后能够累加到2048才行
看了蔡队的代码,用优先队列,取两个最小的,直接相等就合并,不相等就减掉第一个,也只有10多行
以后cf要多看别人代码了,不能说过了就行
#include<bits/stdc++.h>
using namespace std;
using LL=long long;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int T;
cin>>T;
while(T--){
int n;
cin>>n;
int sum=0;
for(int i=0;i<n;++i){
int x;
cin>>x;
if(x<=2048){
sum+=x;
}
}
if(sum>=2048){
cout<<"YES"<<endl;
}else{
cout<<"NO"<<endl;
}
}
return 0;
}
附上我的辣鸡代码:
#include<bits/stdc++.h>
#define maxl 300010
using namespace std;
int n,m,ans;
bool flag;
long long a[maxl];
char s[maxl];
bool in[maxl];
inline void prework()
{
for(int i=1;i<=2048;i++)
a[i]=0;
scanf("%d",&n);
long long x;
for(int i=1;i<=n;i++)
{
scanf("%lld",&x);
if(x>2048)
continue;
for(int j=0;j<20;j++)
if((1<<j)==x && in[x])
a[x]++;
}
}
inline void mainwork()
{
int x;
for(int i=0;i<20;i++)
{
x=1<<i;
a[x*2]+=a[x]/2;
if(x==2048)
break;
}
if(a[2048]>0)
ans=true;
else
ans=false;
}
inline void print()
{
if(ans)
puts("YES");
else
puts("NO");
}
int main()
{
for(int i=0;i<=20;i++)
{
int x=1<<i;
in[x]=true;
if(x==2048)
break;
}
int t=1;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
prework();
mainwork();
print();
}
return 0;
}