A. Square Counting
题意:
给出一个长度为n的数组和数组的和S,构成数组的数要么是从0~n,要么是n*n,求n*n的个数最多是多少个
思路:
默认全是(n*n),那么算个数就直接(n*n)/s
#include<bits/stdc++.h> using namespace std; int main() { long long n,i,j,t,s; cin>>t; while(t--) { cin>>n>>s; //s/(n*n) cout<<s/(n*n)<<endl; } return 0; }
B. Quality vs Quantity
题意:
给出一个长度为n的数组,现在进行染色,可以选择染为红色,蓝色或者不染,问是否可以染色完数组后染色数量少的一方,相加的值大于染色数量多的一方
思路:
可以通过前缀和算,我是排序之后,双指针一个从左边取,一个从右边取。
#include<bits/stdc++.h> using namespace std; const int maxn=2e5+1000; int a[maxn], b[maxn]; int main() { int n,i,j,t; cin>>t; while(t--) { cin>>n; for(i=0;i<n;i++){ cin>>a[i]; } sort(a,a+n); long long ans1=0,ans2=0,flag=0; vector<int >b1,b2; b2.push_back(a[n-1]); ans2+=a[n-1]; j=n-2; for(i=0;i<n;i++){ ans1+=a[i]; b1.push_back(a[i]); while(ans2<=ans1&&j>i) { ans2+=a[j]; b2.push_back(a[j]); j--; } if(ans2>ans1&&b2.size()<b1.size()) { flag=1; } } if(flag==0){ cout<<"No"<<endl; }else { cout<<"Yes"<<endl; } } return 0; } /* 我要选两组数,且第一组的数量小于第二组并且第一组的和大于第二组 第一组肯定先选最大的a[n-1],第二组选两个小的,如果第二组比第一组大,再双指针不停选,总和2e5 应该不会t,处理好就是O(n)的复杂度了 7 3 1 2 3 5 2 8 6 3 1 4 3 5 4 2 5 1000000000 1000000000 1000000000 1000000000 1000000000 5 3 5 6 8 7 */
C. Factorials and Powers of Two
题意:
问一个数n能否全部由2的次幂或者n的阶乘构成,且构成n的数都得不相同
思路:
首先d!如果是小于1e12,那么最多只会有15种,又因为构成n的阶乘数和2的次方的数必须是不相同的
所以可以先枚举n的阶乘,这里使用状态压缩,因为每种数都有选择和不选两种方案,又因为最多就16个数
所以应该是有2^16次方种方案,再用位运算算出取1的时候就是选这个数,最后加起来如果是小于等于n的
再去求2的n次方,这个容易求直接使用位运算算剩下的数字里转为成2进制1的个数即可
最后把个数加起来取最小值
#include<cstdio> #include<algorithm> using namespace std; int t; long long n,fac[20]; int BitCount(long long x) { int res=0; while(x) { res+=(x&1); x>>=1; } return res; } int main() { fac[0]=1; for(int i=1;i<=15;i++) fac[i]=fac[i-1]*i; int tot=(1<<16); scanf("%d",&t); while(t--) { scanf("%lld",&n); int ans=1000; for(int i=0;i<tot;i++) { long long tmp=0; int cnt=0; for(int j=0;j<=15;j++) { if(i & (1<<j)) { tmp+=fac[j]; cnt++; } } if(tmp<=n) ans=min(ans,BitCount(n-tmp) + cnt); } printf("%d\n",ans); } }