贪心法1033 To Fill or Not to Fill 1067 Sort with Swap(0, i)1038 Recover the Smallest Number

在这里插入图片描述
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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

茅蒐Rubia

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值