第一题:
讲解:合并果子原题,选择两个最小的相加,再放回去原序列,一直这样就是答案
至于为什么有人80,是因为每次排序O(nlogn),所以会超时,但是用优先队列就log(n)排序,更加快。
#include <bits/stdc++.h>
using namespace std;
int n;
int main()
{
while(cin>>n,n)
{
priority_queue<int,vector<int>,greater<int> > heap;
int res=0;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
heap.push(x);
}
while(heap.size()>1)
{
int a=heap.top();heap.pop();
int b=heap.top();heap.pop();
heap.push(a+b);
res+=a+b;
}
cout<<res<<endl;
}
return 0;
}
第二题:
讲解:因为最大是910的7次方,所以二进制最多有27位
你就for 1到27
判断n的二进制的哪一位是1
然后就多少次方
输出就行了
#include <bits/stdc++.h>
using namespace std;
long long n;
int main()
{
while(cin>>n,n)
{
double res=n;
int cnt=1;
for(int i=0;i<=27;i++)
{
if(n>>i&1)
res+=1/(double)(1<<cnt);
cnt++;
}
cout<<setiosflags(ios::fixed)<<res<<endl;
}
return 0;
}
第三题:
讲解:三位前缀和,然后O(n^6)取max
#include <bits/stdc++.h>
using namespace std;
#define REP(i,n) for(int i=1;i<=(n);i++)
const int N=30;
int n;
int a[N][N][N];
int s[N][N][N];
int query(int x1,int y1,int z1,int x2,int y2,int z2)
{
return s[x2][y2][z2] - s[x1-1][y2][z2] - s[x2][y1-1][z2] - s[x2][y2][z1-1]
+ s[x1-1][y1-1][z2] + s[x1-1][y2][z1-1] + s[x2][y1-1][z1-1] - s[x1-1][y1-1][z1-1];
}
int main()
{
int T;
cin>>T;
while(T--)
{
int a1,b,c;
cin>>a1>>b>>c;
REP(i,a1) REP(j,b) REP(k,c)
{
cin>>a[i][j][k];
s[i][j][k]=(a[i][j][k]+s[i-1][j][k]+s[i][j-1][k]+s[i][j][k-1]
-s[i-1][j-1][k]-s[i-1][j][k-1]-s[i][j-1][k-1]+s[i-1][j-1][k-1]);
}
int ans=0;
REP(i,a1) REP(j,b) REP(k,c) REP(x,a1) REP(y,b) REP(z,c)
{
ans=max(ans,query(i,j,k,x,y,z));
}
cout<<ans<<endl;
}
return 0;
}
第四题:
讲解:dp
#include <bits/stdc++.h>
using namespace std;
const int N=50,M=40*16000+10;
int n,s;
int a[N];
int f[M];
int main()
{
while(cin>>n>>s,n||s)
{
int sum=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum+=a[i];
}
if((sum-s)%2==1||sum-s<0)
{
cout<<"*"<<endl;
continue;
}
sum=(sum-s)/2;
memset(f,0,sizeof f);
f[0]=1;
for(int i=1;i<=n;i++)
for(int j=sum;j>=a[i];j--)
f[j]+=f[j-a[i]];
if(!f[sum]) cout<<"*"<<endl;
else
{
for(int k=1;k<=n;k++)
{
if(a[k]==0)
{
cout<<"?";
continue;
}
memset(f,0,sizeof f);
f[0]=1;
for(int i=1;i<=n;i++)
{
if(i==k) continue;
for(int j=sum;j>=a[i];j--)
{
f[j]+=f[j-a[i]];
}
}
int op=0;
if(f[sum-a[k]]) op=-1;
if(op==-1&&f[sum]) op=1;
if(op==-1) cout<<"-";
else if(op==1) cout<<"?";
else cout<<"+";
}
cout<<endl;
}
}
return 0;
}