C题:冶炼金属
要根据每次的数据更新最大最小值,转化率最大的可能是直接a除以b,转化率最小的可能需要暴力或者二分查找。每次更新时最大值要取较小的那个,最小值要取最大的那个,这道题数据很小,所以只贴一个暴力找最小值的做法
#include<iostream>
using namespace std;
int main(){
int n,vmin=0,vmax=2e9;
cin>>n;
while(n--){
int a,b;
cin>>a>>b;
int ma=a/b,mn=ma;
while(a/mn<=b)mn--;
mn++;//查到第一次不符合条件时,恢复到上一次就是可能的最小值
vmin=max(vmin,mn);//取最大值的最小项和最小值的最大项
vmax=min(vmax,ma);
}
cout<<vmin<<' '<<vmax;
}
D题:飞机降落
查看评测用规模可知,数据范围只有1e2因此dfs即可
#include<iostream>
using namespace std;
int nowtime,n,flag,t[11],d[11],l[11],st[11];
void dfs(int p){
if(p>=n+1){
flag=1;cout<<'\n';
return;
}
for(int i=1;i<=n;i++)
if(!st[i]&&t[i]+d[i]>=nowtime){
st[i]=1;
if(t[i]<=nowtime){//根据不同情况进行不同的选择
nowtime+=l[i];
dfs(p+1);
nowtime-=l[i];
}else{
int d=nowtime;
nowtime=t[i]+l[i];
dfs(p+1);
nowtime=d;
}
st[i]=0;
}
}
void solve(){
cin>>n;
for(int i=1;i<=n;i++)
cin>>t[i]>>d[i]>>l[i];
flag=0;//初始化标志变量
dfs(1);
if(flag)cout<<"YES\n";
else cout<<"NO\n";
}
int main(){
int t;cin>>t;while(t--)solve();
}
E题:接龙数列
题目要求最小删除数使得数列变为接龙序列,最小删除数得到的是最长的接龙序列,因此直接求最长接龙数列长度,最小删除数=总长度-最长长度
#include<iostream>
using namespace std;
//len纪录以每个数字结尾数列的最长长度,l和r存数字左右两端的数
int n,len[10],l,r,ma;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>l;
r=l%10;
while(l>10)l/=10;
if(len[l]+1>len[r])
len[r]=len[l]+1;
}
for(int i=0;i<=9;i++)ma=max(ma,len[i]);
cout<<n-ma;
}
G题:字串简写
遍历整个字符串求每个位置上及之前a的数量(前缀和),每次遇到b时sum+=之前符合条件的a的个数
#include<iostream>
using namespace std;
int aj[10050],k,sum;
char a,b,s[10050];
int main(){
cin>>k>>s>>a>>b;
for(int i=0;s[i]!=0;i++){
aj[i]=aj[i-1];
if(s[i]==a)
aj[i]++;
else if(s[i]==b)
sum+=aj[i-k+1];
}
cout<<sum;
}