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。。。不过这样改的话这个题就变得比较水了

京公网安备 11010502036488号