题面链接
我有点太糊涂了,或者说懵得太远了,以至于最后一题未解出来。
E Expeditious Cubing
题意:给定四个时间,然后给定目标时间,求第五个时间,使得在去掉一个最快时间和一个最慢时间以后,平均时间小于等于目标时间。
输入格式:第一行四个两位小数$t1,t2,t3,t4$,表示四个时间,第二行一个两位小数$t$,表示目标时间。
输出格式:如果对任意的第五个时间,平均时间都小于等于目标时间,则输出”infinite”;如果果对任意的第五个时间,平均时间都大于目标时间,则输出”impossible”;否则,输出第五个时间,保留两位小数。
算法:分类讨论。总共三种情况:(1)$t$是最小值;(2)$t$是最大值;(3)$t$介于四个时间之间。为了防止精度丢失,最好先把它转化成整型。
#include<bits/stdc++.h>
using namespace std;
int a[4],t;
int main()
{
for(int i=0;i<4;++i){
string s;
cin>>s;
int num=0;
for(int j=0;j<s.size();++j){
if(s[j]=='.')continue;
num=num*10+(s[j]-'0');
}
a[i]=num;
}
sort(a,a+4);
string s;
cin>>s;
for(int i=0;i<s.size();++i){
if(s[i]=='.')continue;
t=t*10+s[i]-'0';
}
if(t*3>=a[1]+a[2]+a[3])puts("infinite");
else if(t*3<a[0]+a[1]+a[2])puts("impossible");
else{
int ans=t*3-a[1]-a[2];
printf("%d.",ans/100);
ans%=100;
printf("%02d",ans);
}
return 0;
}
I Inverted Deck
题意:给定一个序列,问是否能只选择一个区间并倒转它,使得原序列变成非严格递降系列。
输入格式:第一行一个正整数$n$,表示序列的长度。接下来一行输入$n$个正整数表示序列,其中第$i$个数是$a_i$。
$1 \leq n \leq 10^6$,$1 \leq a_i \leq 10^9$。
输出格式:如果一次倒转满足题意,则一行两个正整数$l,r$,分别表示需要交换区间的左右端点;否则输出”impossible”。
算法:设a数组是原数组,b数组是a数组升序排序的结果。从两端比对序列,遇到不相等的地方就停止,然后倒转该区间,判断是否与原数组相同。
#include<bits/stdc++.h>
using namespace std;
int a[10000050],b[10000050],n;
int main(){
cin>>n;
for(int i=1;i<=n;++i)cin>>a[i],b[i]=a[i];
sort(b+1,b+n+1);
int ansl=1,ansr=1;
for(int i=1;i<=n;++i)if(a[i]!=b[i]){
ansl=i;
break;
}
for(int i=n;i>=1;--i)if(a[i]!=b[i]){
ansr=i;
break;
}
if(ansl==ansr&&ansl==1){
puts("1 1");
return 0;
}
for(int i=ansl,j=ansr;i<j;++i,--j){
swap(a[i],a[j]);
}
for(int i=1;i<=n;++i)if(a[i]!=b[i]){
puts("impossible");
return 0;
}
cout<<ansl<<' '<<ansr;
return 0;
}