【贪心与排序】[11.27]

P1056 排座椅
——复习了一遍结构体sort排序
——简单贪(bao)心(li)
——题都没看完就火急火燎敲代码的我简直……一定一定要看完题再敲!!
——RE过,原因是数组开小了
——没能捋清代码逻辑和我的逻辑……我是希望,一个变量记录通道位置,另一个变量记录该通道能隔开的学生对数。显然后者应该直接和通道位置联系起来。但我一开始写的是

stu_y[i].pos=min(ny1,ny2);
stu_y[i].amount++;

显然这个amount和pos就没啥关系了,即使pos相同,那也是分开存在stu_y[i].pos和stu_y[i+1].pos里的

#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;

struct student{
	int pos;//1表示在第一行/列与第二行/列之间隔开 
	int amount;//能隔开的学生对数 
};
bool cmp(student a,student b){
	return a.amount>b.amount;
}
bool cmp2(student a,student b){
	return a.pos<b.pos;
}
student stu_x[2005];
student stu_y[2005];
int main()
{
	int m,n,k,l,d;
	scanf("%d%d%d%d%d",&m,&n,&k,&l,&d);
	int nx1,ny1,nx2,ny2;
	for(int i=1;i<=d;i++){
		scanf("%d%d%d%d",&nx1,&ny1,&nx2,&ny2);
		if(nx1==nx2){
			stu_y[min(ny1,ny2)].pos=min(ny1,ny2);
			stu_y[min(ny1,ny2)].amount++;
		}
		else{
			stu_x[min(nx1,nx2)].pos=min(nx1,nx2);
			stu_x[min(nx1,nx2)].amount++;
		}
	}
	sort(stu_x+1,stu_x+2+m,cmp);
	sort(stu_y+1,stu_y+2+n,cmp);
	//先按能隔开的对数从大到小排序
	sort(stu_x+1,stu_x+k+1,cmp2);
	sort(stu_y+1,stu_y+l+1,cmp2); 
	for(int i=1;i<=k-1;i++) {
		if(stu_x[i].pos==stu_x[i-1].pos) continue;
		else printf("%d ",stu_x[i].pos);
	}
	printf("%d",stu_x[k].pos);
	printf("\n");
	for(int i=1;i<=l-1;i++) {
		if(stu_y[i].pos==stu_y[i-1].pos) continue;
		printf("%d ",stu_y[i].pos);
	}
	printf("%d",stu_y[l].pos);
	return 0;
}

P1094 纪念品分组

我乱写的……这都能过?!
大概就是排序之后将最小的和最大的搭配,从两端逼近中间,搭配完了改数字记为不可用,当i,j相遇就结束搭配,查一查还有哪个数还没搭配过,单独分成一组

#include<stdio.h>
#include<algorithm>
using namespace std;
int a[30005];

int main()
{
	int w,n,ans=0;
	scanf("%d%d",&w,&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	sort(a+1,a+n+1);
	int ok=1;
	for(int i=1;i<n;i++){
		for(int j=n+1-i;j>1;j--){
			if(i==j){
				ok=0;
				break;
			}
			if(a[i]+a[j]>w) continue;
			else {
				a[j]=w+1;
				a[i]=w+1;
				ans++;
				break;
			}
		}
		if(ok==0) break;
	}
	for(int i=1;i<=n;i++){
		if(a[i]<=w) ans++;
	}
	printf("%d",ans);
	return 0;
}

P1478 陶陶摘苹果(升级版)

先想到一个最朴素的解决方案,然后朴素地按步骤写了(比如多余的挑苹果步骤)(考虑到后面的冒泡排序,当数据量特别大的时候这个剪枝也许有点用吧)
冒泡排序以及结构体数组也是现学现用了,就当练习吧

#include<stdio.h>
//在能够到的苹果中优先选择耗费力气最小的 
int x[5005];
int y[5005];

//定义一个将一个苹果的高度与消耗力气捆绑在一起的结构体 
struct apple
{
	int height;
	int effort;
};

int main(){
	int n,s,a,b;
	scanf("%d%d%d%d",&n,&s,&a,&b);
	for(int i=1;i<=n;i++){
		scanf("%d%d",&x[i],&y[i]);
	}
	//挑选出够得到的苹果 
	//其实这一段很多余
	struct apple app[5005];
	int i=1;
	for(int j=1;i<=n;i++){
		if(x[i]<=a+b){
		app[j].height=x[i];
		app[j].effort=y[i];
		j++;}
	}
	//按力气消耗从小到大进行冒泡排序
	for(int k1=1;;k1++) {
		if(app[k1].height==0) break;
		for(int k2=k1+1;;k2++){
			if(app[k2].height==0) break;
			if(app[k1].effort>app[k2].effort)
			{
				//交换height和effort 
				//应该写个swap函数的,但没有(
				int t=app[k1].effort;
				app[k1].effort=app[k2].effort;
				app[k2].effort=t;
				t=app[k1].height;
				app[k1].height=app[k2].height;
				app[k2].height=t;
			}
		}
	}
	int z=1;
	int ans=0;
	while(s-app[z].effort>=0&&app[z].height>0){
		ans++;
		s-=app[z].effort;
		z++;
	}
	printf("%d",ans);

	return 0;
}
发布了28 篇原创文章 · 获赞 0 · 访问量 683

猜你喜欢

转载自blog.csdn.net/weixin_45561591/article/details/102591774