Sample Input 1:
50 1300 12 8
6.00 1250
7.00 600
7.00 150
7.10 0
7.20 200
7.50 400
7.30 1000
6.85 300
Sample Output 1:
749.17
Sample Input 2:
50 1300 12 2
7.10 0
7.00 600
Sample Output 2:
The maximum travel distance = 1200.00
#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 501
int c,n;
double d,v;
typedef struct NODE{
double price;
double distance;
}station;//加油站
station sta[maxn];
bool cmp(station a,station b)//根据离原点的距离从小到大排序
{
return a.distance<b.distance;
}
int main()
{
scanf("%d%lf%lf%d",&c,&d,&v,&n);
for(int i=0;i<n;i++)
scanf("%lf%lf",&sta[i].price,&sta[i].distance);
sta[n].price=0;sta[n].distance=d;//最后一个加油站距离原点d米,油价0
sort(sta,sta+n,cmp);
if(sta[0].distance!=0)
{
printf("The maximum travel distance = 0.00\n");
return 0;
}
double now=0,rem=0;//now是当前已经行驶的距离,rem是车里剩余的油还能走的距离
int pos=0;//是所处加油站的标号
double maxdis=c*v;//骑车可以行驶的最大距离
double sum=0;//计数当前所花费的价格
int dis=0;//记录要前往的下一个加油站离当前加油站的距离
while(now<d)
{
int i;
rem=rem-dis;
int min=pos+1;
for(i=pos+1;sta[i].price>=sta[pos].price&&sta[i].distance<=now+maxdis&&i<=n;i++)
if(sta[min].price>sta[i].price)
min=i;
if(sta[i].distance<=now+maxdis&&i<=n)
{
dis=sta[i].distance-sta[pos].distance;
sum+=(double)(dis-rem)/v*sta[pos].price;
rem=dis;
pos=i;
now=sta[i].distance;
continue;
}
if(sta[min].distance<=now+maxdis&&i<=n)
{
dis=sta[min].distance-sta[pos].distance;
sum+=(double)(maxdis-rem)/v*sta[pos].price;
rem=maxdis;
pos=min;
now=sta[min].distance;
continue;
}
now+=maxdis;
printf("The maximum travel distance = %.2lf\n",now);
return 0;
}
printf("%.2lf\n",sum);
return 0;
}
主要在于分类讨论各个策略。
Sample Input:
10
3 5 7 2 6 4 9 0 8 1
Sample Output:
9
#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 100001
int a[maxn];
int main()
{
int n;
scanf("%d",&n);
int i;
int sum=0,num=0;
for(i=0;i<n;i++)
{
int m;
scanf("%d",&m);
a[m]=i;//意思是,数字m所在的位置在i号
if(i!=m)
num++;//记录不在原位的数字个数
}
i=1;
while(num)
{
int m;
if(a[0]==0&&num)
{
while(a[i]==i&&i<n)
i++;
m=a[i];
a[0]=m;
a[i]=0;
sum++;
num++;//由于把0的位置错位,所以这里不正确位置的数目要加一
continue;
}
m=a[0];
a[0]=a[m];
a[m]=m;
num--;
if(a[0]==0)
num--;//碰巧交换后0也复位,m也复位,那么num应该减去两次
sum++;
}
printf("%d",sum);
return 0;
}
错误代码:
两个结点运行超时,错误在i=1的地方
#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 100001
int a[maxn];
int main()
{
int n;
scanf("%d",&n);
int i;
int sum=0,num=0;
for(i=0;i<n;i++)
{
int m;
scanf("%d",&m);
a[m]=i;
if(i!=m)
num++;
}
while(num)
{
int m;
if(a[0]==0&&num)
{
i=1;//错误在这,因为过于重复。正确结果可见上个代码的修正
while(a[i]==i&&i<n)
i++;
m=a[i];
a[0]=m;
a[i]=0;
sum++;
num++;
continue;
}
m=a[0];
a[0]=a[m];
a[m]=m;
num--;
if(a[0]==0)
num--;
sum++;
}
printf("%d",sum);
return 0;
}
Sample Input:
5 32 321 3214 0229 87
Sample Output:
22932132143287
错误示例1:
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
#define maxn 10001
string s[maxn];
bool cmp(string a,string b)
{
return a+b<b+a;
}
int main()
{
int n;
cin>>n;
int num=n;
for(int i=0,k=0;k<n;i++,k++)
{
cin>>s[i];
int j;
for(j=0;s[i].size()&&s[i][j]=='0';)//这样就删除了所有字符串的前面的0字符
s[i].erase(s[i].begin());
if(s[i].size()==0)
{
num--;
i--;
}
}
sort(s,s+num,cmp);
for(int i=0;i<num;i++)
cout<<s[i];
cout<<endl;
return 0;
}
显然,087前面的0不应该丢掉的,但在这个代码里却被擦去了
错误示例2:
考虑全部为0的情况
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
#define maxn 10001
string s[maxn];
bool cmp(string a,string b)
{
return a+b<b+a;
}
int main()
{
int n;
cin>>n;
int num=n;
for(int i=0;i<n;i++)
cin>>s[i];
sort(s,s+num,cmp);
for(int j=0;s[0].size()&&s[0][j]=='0';)
s[0].erase(s[0].begin());//这样只删除了第一个最小字符串的0字符,却可能出现以下情况
if(s[0].size())
cout<<s[0];
for(int i=1;i<num;i++)
cout<<s[i];
cout<<endl;
return 0;
}
正确答案:
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
#define maxn 10001
string s[maxn];
bool cmp(string a,string b)
{
return a+b<b+a;
}
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>s[i];
sort(s,s+n,cmp);
string str;
for(int i=0;i<n;i++)
str+=s[i];
for(;str.size()&&str[0]=='0';)
str.erase(str.begin());
if(str.size()==0)
cout<<0<<endl;
else
cout<<str<<endl;
return 0;
}