A
知识点:implementation
思路:分别统计A B C D四个字符的个数,然后判断一下就行了。
#include<bits/stdc++.h> using namespace std; #define ll long long int main(){ ll n,t,i,j,k; cin>>t; while(t--){ string s; cin>>s; int a=0,b=0,c=0,d=0; for(i=0;i<4;i++){ if(s[i]=='A')a++; if(s[i]=='B')b++; if(s[i]=='C')c++; if(s[i]=='D')d++; } if(d||c>=2)cout<<"failed\n"; else if(!d&&a>=3)cout<<"sp offer\n"; else cout<<"offer\n"; } }
B
知识点:greedy,game
思路:这道题其实有歧义,应该加一句“每个人都不希望自己出局的前提下,希望出局的人越多越好”。
这样的话,每个人一定会拿“能拿牌最少数量”的那个人,这样这个人就一定会被淘汰掉。
当剩余的人数不大于剩余的 时,就永远不会有人淘汰了。
#include<bits/stdc++.h> using namespace std; #define ll long long ll a[111111]; int main(){ ll n,t,i,j,k; cin>>n; for(i=0;i<n;i++)cin>>a[i]; sort(a,a+n); for(i=0;i<n;i++){ if(a[i]>=n-i-1)break; } cout<<n-i; }
C
知识点:greedy,math
第一天显然是让最大的 个 翻3倍,剩下的最大的 个 翻2倍。
从第二天开始,如果继续让最大的 个 翻3倍,剩下的最大的 个 翻2倍,那么剩下的人就会被淘汰掉。但是很明显哪怕淘汰了这些人,最终的结果也是最大的。因为淘汰的本就是 最小的那一批,连翻两倍的那部分 都比不过。
所以最终的结果就是让最大的 个 翻 次3倍,剩下的最大的 个 翻 次2倍,然后判断一下最后那部分人有没有淘汰掉就可以了(也就是判断 是否是1)。
注意要用快速幂加速。
#include<bits/stdc++.h> using namespace std; #define ll long long int mod =1e9+7; ll power(ll a,ll b){ ll res=1; while(b){ if(b&1)res=res*a%mod; b>>=1; a=a*a%mod; } return res; } ll a[111111]; int main(){ // freopen("tiaoxin.in","r",stdin); ll n,m,x,y,t,i,j,k; cin>>n>>m>>x>>y; for(i=0;i<n;i++)cin>>a[i]; sort(a,a+n); ll res=0; if(m==1){ for(i=n-1;i>=n-x;i--){ res+=a[i]*3; } for(i=n-x-1;i>=n-x-y;i--){ res+=a[i]*2; } for(;i>=0;i--){ res+=a[i]; } cout<<res%mod; return 0; } for(i=n-1;i>=n-x;i--){ res+=a[i]*power(3,m)%mod; } for(;i>=n-x-y;i--){ res+=a[i]*power(2,m)%mod; } cout<<res%mod; return 0; }
D
这道题没过,官方给的题解好像是错的,我稍微云一下题解吧。
可以得出结论,操作1等价于让某个数除以素数 ,操作2等价于让某个数乘以素数 。由于每个素数又是独立的,那么这道题就等价于这样:
已知每个素数 在每个数 里出现的次数,每次可以操作可以让某个数的p的次数加一或减一,求让所有次数相等的最小操作数。
这样答案就很明显了,把所有数中的 的次数变成所有次数的中位数就可以了。这样操作次数就是最小的。下面我分享一下我做题中想到的思路(因为复杂度太大了所以没码)
先筛出所有素数,然后枚举每个素数在每个数中的出现的次数,然后求中位数。
复杂度:线性筛 ,素数个数大致为 ,计算单独一个数的素因子个数为 ,计算中位数复杂度为 ,最终复杂度为 ,总复杂度约为
这样如果 是 数量级那么我这个思路是可行的,但由于 达到了1e6,所以直接暴毙,码都懒得去码了ORZ
期待出题人更新正确的题解。
upd:出题人已经把题目修改了,让操作2去世,只剩下的操作1。。。emmm。。。不过这样改的话这个题就变得比较水了