Codeforces Round #638 (Div. 2)
地址:http://codeforces.com/contest/1348
题意:2^1,2^2....2^n,分成两部分,使两部分的差最小。
解析:可以发现,n越大,2^n越大,和前面的差距越来越大。所以第一部分先把2^n先加入,再陆续加入2^1,2^2.....直到n/2个即可。
#include<iostream> #include<cstdio> #include<cmath> typedef long long ll; using namespace std; int main() { int t; cin>>t; while(t--) { ll n; cin>>n; ll sum=0; for(int i=1;i<=n;i++) sum+=pow(2,i); ll sum2=pow(2,n); int ans=1; // cout<<sum<<endl; for(int i=1;i<=n;i++) { if(ans==n/2) break; sum2+=pow(2,i); // cout<<sum2<<endl; ans++; } cout<<fabs(sum-sum2-sum2)<<endl; } }
题意:给出n个数和k,把所给数组变成每k个的和都相等。操作是添加任意的1-n之间的数字到任意位置。输出任意答案,否则输出-1
解析:可以推出,当所给数组的种类数>k时,是肯定构造不出的,所以直接输出-1。那么种类数ans<=k时,如果ans==k,那么可以把每个数都扩成k个数,包含所有种类且不重复,这样就满足了每k个数和相等而且符合原数组的顺序。ans<k时,操作一样,只是不够K个的部分用同一个数字填充就可以了。对题中给的最后一个样例,我们可以输出这个:n*k=16,2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1
#include<iostream> #include<cstdio> #include<map> #include<cmath> typedef long long ll; using namespace std; const int maxn=1e4+10; int a[maxn]; int b[maxn]; int main() { int t; cin>>t; while(t--) { int n , k ; cin>>n>>k; map<int,int>mp; for(int i =1;i<=n;i++) { cin>>a[i]; mp[a[i]]++; } int ans=0; for(int i=1;i<=n;i++) { if(mp[i]!=0) ans++; } if(ans>k) { cout<<"-1"<<endl; } else { int tot=1; for(int i=1;i<=n;i++) { if(mp[i]!=0) b[tot++]=i; } if(ans<k) { for(int i=ans+1;i<=k;i++) b[tot++]=1; } // for(int i=1;i<tot;i++) // cout<<b[i]<<" "; // cout<<endl; cout<<n*k<<endl; for(int i = 1; i <= n ; i++) { for(int j=1;j<tot;j++) cout<<b[j]<<" "; } cout<<endl; } } }
题意:初始只有1个细胞,权值为1,可以在白天选择分裂和不分裂,晚上权值会+1。问权值和达到n,最少需要几天,并输出每天多少细胞要分裂。
解析:很明显,分裂后再全体+1肯定比不分裂权值+1增加的多,所以对于全分裂,这里是权值最大值,全体不分裂,是权值最小值,所以可以得出每一天的权值区间:
[2,1+2] [3,1+2+4] [4,1+2+4+8]。
因为问最少需要多少天,肯定是让他们尽量分裂。所以只看最大权值的变化,是:2^0+2^1+2^2.....得出这个sum值,如果sum==n,那么正好,否则把n-sum加入到vector中,再排个序,v[i]-v[i-1]就是每天需要分裂的细胞数了(这个可以手动推出的)。
#include<iostream> #include<algorithm> #include<cstdio> #include<vector> using namespace std; typedef long long ll; int main() { int t; cin>>t; while(t--) { ll n ; cin>>n; vector<ll>v; for(int i=1;i<=n;i<<=1) { v.push_back(i); n=n-i; } if(n) v.push_back(n); sort(v.begin(),v.end()); cout<<v.size()-1<<endl; for(int i=1;i<v.size();i++) cout<<v[i]-v[i-1]<<" "; cout<<endl; } }