2 条题解

  • 1
    @ 2023-11-28 22:41:19

    贪心,尽可能充分利用每只独木舟。这套题贪心策略很好想,但实现起来还是挺有意思的。

    原来我的思路是先对体重数组从大到小排序,然后两层循环逐个配对,配对成功则标记筛出,时间复杂度为O(n^2),我自信满满地提交,结果顺理成章地50 Time Exceeded了。

    要想通过此题,那么时间复杂度就得是O(n),也就相当于只能使用一次遍历。那么怎样才能一次遍历解决问题呢?每个元素只可以被访问一次,但逐个配对又需要n次,能否只执行一次配对呢?随后灵光一闪,对于有序数组而言,若想配对,那就得是数组左边和右边相对,我们可以使用栈来存储体重,在遍历的过程中,如果空栈或者无法与栈顶元素(由于数组是有序的,遍历是有序的,那么栈也是有序的,如果栈顶都无法配对成功,就更不必考虑栈内其他元素了)配对就入栈,入栈即使用了一个新的独木舟,则计数。若配对成功,则弹出栈顶。如此,一次遍历便可解决。提交,100 Accepted

    #include<iostream>
    #include<algorithm>
    using namespace std;
    int a[30001];//存储体重
    int b[30001]={0};//初始化栈
    int  k=0;//栈顶指针
    bool cmp(int x,int y){//sort比较器
    	return x>y;
    }
    int main(){
    	int w,n,ans=0;
    	cin>>w>>n;
    	for(int i=1;i<=n;i++) cin>>a[i];
    	sort(a+1,a+n+1,cmp);//体重从大到小排序
    	a[0]=200;//设置前导元素,以保证空栈时程序正常运行
    	for(int i=1;i<=n;i++){
    		if(a[i]+a[b[k]]<=w) k--;//若与栈顶体重之和在最大载重量内,则弹出栈顶
    		else b[++k]=i,ans++;//入栈
    	}
    	cout<<ans;
    	return 0;
    }
    
  • 0
    @ 2024-12-14 21:47:29

    贪心 用的while语句,没用2层for循环

    #include <bits/stdc++.h>
    using namespace std;
    int w,n,a[30010],ans=0;
    int main(){
    	//freopen("kaj.in","r",stdin);
    	//freopen("kaj.out","w",stdout);
    	cin>>w>>n;
    	for(int i=1;i<=n;i++){
    		cin>>a[i];
    	}
    	sort(a+1,a+n+1);
    	int i=1,y=n;
    	while(i<=y){//从小匹配大的 
    		if(a[i]+a[y]<=w){
    			ans++;
    			i++;
    			y--;
    		}else{
    			ans++;
    			y--;
    		}
    	}//两边同时进行,加减数 
    	cout<<ans;
    	return 0;
    }
    

    仅供参考

    • 1

    信息

    ID
    444
    时间
    1000ms
    内存
    256MiB
    难度
    8
    标签
    递交数
    133
    已通过
    24
    上传者