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;
}
我乱写的……这都能过?!
大概就是排序之后将最小的和最大的搭配,从两端逼近中间,搭配完了改数字记为不可用,当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;
}
先想到一个最朴素的解决方案,然后朴素地按步骤写了(比如多余的挑苹果步骤)(考虑到后面的冒泡排序,当数据量特别大的时候这个剪枝也许有点用吧)
冒泡排序以及结构体数组也是现学现用了,就当练习吧
#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;
}