7.13取法乎上仅得乎中

1070 Mooncake (25)(25 分)

Mooncake is a Chinese bakery product traditionally eaten during the Mid-Autumn Festival. Many types of fillings and crusts can be found in traditional mooncakes according to the region's culture. Now given the inventory amounts and the prices of all kinds of the mooncakes, together with the maximum total demand of the market, you are supposed to tell the maximum profit that can be made.

Note: partial inventory storage can be taken. The sample shows the following situation: given three kinds of mooncakes with inventory amounts being 180, 150, and 100 thousand tons, and the prices being 7.5, 7.2, and 4.5 billion yuans. If the market demand can be at most 200 thousand tons, the best we can do is to sell 150 thousand tons of the second kind of mooncake, and 50 thousand tons of the third kind. Hence the total profit is 7.2 + 4.5/2 = 9.45 (billion yuans).

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive integers N (<=1000), the number of different kinds of mooncakes, and D (<=500 thousand tons), the maximum total demand of the market. Then the second line gives the positive inventory amounts (in thousand tons), and the third line gives the positive prices (in billion yuans) of N kinds of mooncakes. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the maximum profit (in billion yuans) in one line, accurate up to 2 decimal places.

Sample Input:

3 200
180 150 100
7.5 7.2 4.5

                               

#include <cstdio>
#include <algorithm>
using namespace std;
struct mooncake{
	double price,num,sum;//num数量,sum总价钱 
}cake[1001];
bool cmp(mooncake a,mooncake b)
{
	return a.price>b.price;
}
int main()
{
	int n,d;
	double total=0;
	scanf("%d %d",&n,&d);
	for (int i=0;i<n;i++)
	{
		scanf("%lf",&cake[i].num);
	}
	for(int i=0;i<n;i++)
	{
		scanf("%lf",&cake[i].sum);
		cake[i].price=cake[i].sum/cake[i].num;
	}
	sort(cake,cake+n,cmp);
	for(int i=0;i<n;i++)
	{
		if(cake[i].num>=d)
		{
		 total+=d*cake[i].price;
		 break;
		}
		else
		{
			total+=cake[i].sum;
			d-=cake[i].num;
		}
	}
	printf("%.2lf",total);
	return 0;
} 
#include <cstdio>
#include <algorithm>
using namespace std;
struct station{
	double pi,di;
}st[510];
bool cmp(station a,station b)
{
	return a.di<b.di;
}
int main()
{
	double cmax,d,davg;//n若设置为double型 则不能进入数组调用 
	int n;
	scanf("%lf%lf%lf%d",&cmax,&d,&davg,&n);
	for(int i=0;i<n;i++)
	{
		scanf("%lf%lf",&st[i].pi,&st[i].di);	
	}
	st[n].pi=0.0;//数组最后面放置终点 价格为0 虚拟的站点 
	st[n].di=d;//数组最后面放置距离d  方便与n-1个相减 判断最后是否能到达 
	sort(st,st+n,cmp);
	if(st[0].di!=0)
	  printf("The maximum travel distance = 0.00\n");//如果起点处没有站点 则达到不了
	else
	{
		int now=0;
		double ans=0,nowtank=0,maxi=cmax*davg;//总花费开始为0 当前油量为nowtank max加满一桶能走多少米
		while(now<n)//每次循环出下一个选择到达的加油站 
		{
			int k=-1;//最低油价的加油站编号 
			double pricemin=100000000;
			for(int i=now+1;i<=n&&st[i].di-st[now].di<=maxi;i++)
			{//选出当前加油站加满油能到达的第一个油价低于当前的加油站 若没有 输出高于当前但是价格最低的 
				if(st[i].pi<pricemin)//包括最后终点 虚拟站点 
				{
					pricemin=st[i].pi;//更新最低价格 
				    k=i;
				}//若找到第一个比当前油价便宜的 弹出 
				if(st[now].pi>pricemin)
				{
					break;
				} 
			}
			if(k==-1) break;//满油情况任何都无法到达 
			double need=(st[k].di-st[now].di)/davg;//计算两个加油站之间需要的油量
			if(pricemin<st[now].pi)
			{
				if(nowtank<need)
				{
					ans+=(need-nowtank)*st[now].pi;
					nowtank=0;
				}
				else{
					nowtank-=need;//能省一点是一点 直接到达下一个便宜的再加满油 
			     	}
		    }
			else//当前的比较便宜
			{
				ans+=(cmax-nowtank)*st[now].pi;
				nowtank=cmax-need;//到达以后油量减少 
			} 
				now=k;//进入下一次寻找过程 
		} 
		if(now==n)  printf("%.2f\n",ans);//到达最终虚拟站点 
		else printf("The maximum travel distance = %.2f\n",st[now].di+maxi);//每个加油站油量都是充足的  只是桶大小有限一次最多走maxi 
	}
	return 0;
}
比较难的贪心算法  刚开始把n设为double型 结果数组调用不了  






1037 Magic Coupon (25)(25 分)

The magic shop in Mars is offering some magic coupons. Each coupon has an integer N printed on it, meaning that when you use this coupon with a product, you may get N times the value of that product back! What is more, the shop also offers some bonus product for free. However, if you apply a coupon with a positive N to this bonus product, you will have to pay the shop N times the value of the bonus product... but hey, magically, they have some coupons with negative N's!

For example, given a set of coupons {1 2 4 -1}, and a set of product values {7 6 -2 -3} (in Mars dollars M\$) where a negative value corresponds to a bonus product. You can apply coupon 3 (with N being 4) to product 1 (with value M\$7) to get M\$28 back; coupon 2 to product 2 to get M\$12 back; and coupon 4 to product 4 to get M\$3 back. On the other hand, if you apply coupon 3 to product 4, you will have to pay M\$12 to the shop.

Each coupon and each product may be selected at most once. Your task is to get as much money back as possible.

Input Specification:

Each input file contains one test case. For each case, the first line contains the number of coupons NC, followed by a line with NC coupon integers. Then the next line contains the number of products NP, followed by a line with NP product values. Here 1<= NC, NP <= 10^5^, and it is guaranteed that all the numbers will not exceed 2^30^.

Output Specification:

For each test case, simply print in a line the maximum amount of money you can get back.

Sample Input:

4
1 2 4 -1
4
7 6 -2 -3

Sample Output:

43

#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=100010;
int coupon[maxn],product[maxn];
bool cmp(int a,int b)
{
	return a<b;//可以不写 直接调用默认为从小到大排序 
}
int main()
{
	int n,m;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	  scanf("%d",&coupon[i]);
	scanf("%d",&m);
	for(int i=0;i<m;i++)
	  scanf("%d",&product[i]);
	sort(coupon,coupon+n,cmp);
	sort(product,product+m,cmp);
	int i=0,j,ans=0;//ans放乘积之和 
	while(i<n&&i<m&&coupon[i]<0&&product[i]<0) 
	{
		ans+=coupon[i]*product[i];
		i++;
	}//开始为负 可以同步表示 
	i=n-1;
	j=m-1;//若开始为正 从后往前数 
	while(i>=0&&j>=0&&coupon[i]>0&&product[j]>0)
	{
		ans+=coupon[i]*product[j];
		i--;
		j--;
	}
	printf("%d\n",ans);
	
	return 0;
}

题目太.....coupon就是兑换券的意思

这种ij mn比较多的题目一定不能简单复制  有个地方把i写成j看了十分钟

1067 Sort with Swap(0,*) (25)(25 分)

Given any permutation of the numbers {0, 1, 2,..., N-1}, it is easy to sort them in increasing order. But what if Swap(0, *) is the ONLY operation that is allowed to use? For example, to sort {4, 0, 2, 1, 3} we may apply the swap operations in the following way:

Swap(0, 1) => {4, 1, 2, 0, 3}\ Swap(0, 3) => {4, 1, 2, 3, 0}\ Swap(0, 4) => {0, 1, 2, 3, 4}

Now you are asked to find the minimum number of swaps need to sort the given permutation of the first N nonnegative integers.

Input Specification:

Each input file contains one test case, which gives a positive N (<=10^5^) followed by a permutation sequence of {0, 1, ..., N-1}. All the numbers in a line are separated by a space.

Output Specification:

For each case, simply print in a line the minimum number of swaps need to sort the given permutation.

Sample Input:

10 3 5 7 2 6 4 9 0 8 1

Sample Output:

9

#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=100010;
int pos[maxn];//存放各个数字当前所处的位置编号 
int main()
{
	int n,ans=0;//ans表示总交换次数 
	scanf("%d",&n);
	int left=n-1,num;
	for(int i=0;i<n;i++)
    {
	   scanf("%d",&num);
	   pos[num]=i;
	   if(num==i&&num!=0)
	   left--; 
	} //left存放除了0以外不在本位上的数的个数 
	int k=1;//k存放除了0以外不在本位上的最小的数
	while(left>0)
	{
		if(pos[0]==0)
		{
		  while(k<n)
		   {
		   	if(pos[k]!=k)//没归位
		   	{
		   		swap(pos[0],pos[k]);
		   		ans++;
		   		break;
		   	}
		   	k++;//k数 在本位  找下一个不在本位的 
		   }
		} //当前0又跳离了0的位置 
		while(pos[0]!=0)
		{
			swap(pos[0],pos[pos[0]]);
			
				ans++;
				left--;
            //只要0跳离0之后 就可以和当前位置的数交换位置 归位一个 
			
		} 
		
	}
	printf("%d\n",ans); 
	return 0;
}

比较烧脑的一道题 需二刷

0是一个关键的数

0应当是最后排好序的  k记录除了0以外最小的不在本位的数  若k跳到n时 只有0没归位 循环结束

若0先跳到了0位 则0和最小的没归位的交换

交换后0的位置可以帮助归位一个数

最终0停在0  剩余的除了0需要排序的数也为0 结束

今天竟然这个点就写完了  

杏呼

猜你喜欢

转载自blog.csdn.net/Coding18/article/details/81038304
今日推荐