stl数据库:
A题
Problem ID: 15690
Contest ID: 5887
子串计算:
核心思路就是map会自动排序(string 类型以字典序排序),而输出正好要字典序,
因此只需暴力枚举string的每一段,为map中该段的数量加一,在输出时判断一下该段的数量大于1就行。
附上代码:
#include<bits/stdc++.h>
using namespace std;
string s;
map<string,int> mp;
int main(){
cin>>s;
for(int i=0;i<s.length();i++){
for(int j=1;j<=s.length()-i;j++){
mp[s.substr(i,j)]++;
}
}
for(auto it=mp.begin();it!=mp.end();it++){
if(it->second>1){
cout<<it->first<<" "<<it->second<<endl;
}
}
return 0;
}
贪心:
A题
Problem ID: 9172
Contest ID: 5888
异或与乘积
这题经过整理,可以发现在大多数情况下,异或得到的结果是不大于乘积的,只有在1乘以一个偶数时才会比1异或一个偶数小,也就是说我们要尽可能多的找到1与偶数异或(即使部分偶数加一)
不难发现要使结果最大,应尽量让1去与小的偶数异或,且异或后不能再次异或,否则会变成减小一位。
过程就是统计一的个数,将一的个数个偶数(优先选小的)加一,然后全部相乘。
附代码:
#include<bits/stdc++.h>
using namespace std;
long long j[114514],o[114514];
int n,ct1,ctj,cto;
long long ans=1;
const long long mod=1000000007;
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
long long x;
scanf("%lld",&x);
if(x==1){
ct1++;
}else if(x%2==0){
o[cto++]=x;
}else{
j[ctj++]=x;
}
}
sort(o,o+cto);
for(int i=0;i<min(ct1,cto);i++){
o[i]++;
}
for(int i=0;i<cto;i++){
ans=ans*o[i]%mod;
}
for(int i=0;i<ctj;i++){
ans=ans*j[i]%mod;
}
printf("%lld",ans);
return 0;
}
B题
Problem ID: 9737
Contest ID: 5888
平衡后缀
这题的思路很简单,就像拼拼图一样,把原先的字符串给拆开,统计每种字母的数量,然后遍历,将每个字母放入新的字符串内,每次都优先选择字典序靠前的字母放入,放入后看未放入的字母是否满足条件(即最大值减最小值是否小于等于k),若不满足,就换个字母放入,最后输出字符串,若有一个位子不管放什么字母都不行,输出-1。
附代码
#include<bits/stdc++.h>
using namespace std;
long long n,k,T;
string s;
bool b,b2;
map<char,long long> c;
map<char,bool> c2;
char findmax(){
char maxc='!';
long long maxn=-1;
for(int i=0;i<26;i++){
if(c[(char)('a'+i)]>maxn){
maxc=(char)('a'+i);
maxn=c[(char)('a'+i)];
}
}
return maxc;
}
char findmin(){
char minc='!';
long long minn=INT_MAX;
for(int i=0;i<26;i++){
if(c[(char)('a'+i)]<minn&&c2[(char)('a'+i)]!=0){
minc=(char)('a'+i);
minn=c[(char)('a'+i)];
}
}
return minc;
}
int main(){
scanf("%lld",&T);
while(T--){
c.clear();
scanf("%lld%lld",&n,&k);
cin>>s;
for(int i=0;i<s.length();i++){
c[s[i]]++;
c2[s[i]]=true;
}
b2=false;
if(c[findmax()]-c[findmin()]>k){
cout<<-1<<endl;
continue;
}
for(int j=0;j<s.length();j++){
b=false;
for(int i=0;i<26;i++){
if(c[(char)('a'+i)]==0){
continue;
}else{
c[(char)('a'+i)]--;
if(c[findmax()]-c[findmin()]<=k){
b=true;
s[j]=(char)('a'+i);
break;
}
c[(char)('a'+i)]++;
}
}
if(!b){
cout<<-1<<endl;
b2=true;
break;
}
}
if(!b2){
cout<<s<<endl;
}
}
return 0;
}
C题
Problem ID: 9897
Contest ID: 5888
CCC(什么鬼名字啊喂)
众所周知,一个数除一个2比除两个2肯定要更大一点,也就是说n/2^x>n/2^y(x<y),在数组最前面的数肯定除2的次数多,在后面的则少,为了让结果更大,更大的数要除更少的2,即整个数组要从小到大排再运算。
附代码
#include<bits/stdc++.h>
using namespace std;
int a[105];
int n,k;
double ans;
bool cmp(int a,int b){
return a>b;
}
int main(){
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
sort(a,a+n,cmp);
for(int i=k-1;i>=0;i--){
ans=(double)(ans+(double)a[i])/2;
}
printf("%.5lf",ans);
return 0;
}
F题
Problem ID: 15700
Contest ID: 5888
奶牛玩杂技
这题思路很简单,因为每头牛的压力指数=前面所有牛的压力指数-那头牛的力量,也就是说,为了不压死别的牛,靠上的牛要轻一点(即靠下的要重一点),同时牛本身的力量要大,越靠下,力量要越大越好,综合起来考虑,我们可以通过重量加力量作为一头牛的指标,从小到大排,最后遍历一手求最大值,解释不下去了,看代码吧(千万注意,测试点有负数情况!!!)
代码:
#include<bits/stdc++.h>
using namespace std;
long long n,sum,ans=INT_MIN;
struct node{
long long x,y;
}a[50005];
bool cmp(node a,node b){
return (a.x+a.y)<(b.x+b.y);
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i].x>>a[i].y;
}
sort(a,a+n,cmp);
for(int i=0;i<n;i++){
sum=0;
for(int j=0;j<i;j++){
sum+=a[j].x;
}
sum-=a[i].y;
ans=max(ans,sum);
}
cout<<ans;
return 0;
}
这个帖子就先到这了,过会再发一些