【c/c++算法刷题笔记】—— 洛谷闯关1.9 综合练习

P1478 陶陶摘苹果(升级版)

题目描述

又是一年秋季时,陶陶家的苹果树结了 nn 个果子。陶陶又跑去摘苹果,这次他有一个 aa 公分的椅子。当他手够不着时,他会站到椅子上再试试。

这次与 NOIp2005 普及组第一题不同的是:陶陶之前搬凳子,力气只剩下 ss 了。当然,每次摘苹果时都要用一定的力气。陶陶想知道在 s<0s<0 之前最多能摘到多少个苹果。

现在已知 nn 个苹果到达地上的高度 x_i ,椅子的高度 aa,陶陶手伸直的最大长度 bb,陶陶所剩的力气 ss,陶陶摘一个苹果需要的力气 y_iy,求陶陶最多能摘到多少个苹果。

输入格式
第 11 行:两个数 苹果数 nn,力气 ss。
第 22 行:两个数 椅子的高度 aa,陶陶手伸直的最大长度 bb。
第 33 行~第 3+n-13+n−1 行:每行两个数 苹果高度 x_i,摘这个苹果需要的力气 y_i

输出格式
只有一个整数,表示陶陶最多能摘到的苹果数。

样例

输入 #1复制
8 15
20 130
120 3
150 2
110 7
180 1
50 8
200 0
140 3
120 2

输出 #1复制
4

说明/提示
对于 100%100% 的数据,n≤5000, a≤50, b≤200, s≤1000, x_i≤280, y_i ≤100。

笔记
  • 把不满足条件的筛去,只保存可用的 体力值,把体力值从小到大排序
代码
#include <iostream>
#include<algorithm>
using namespace std;

int main()
{
    int n,s,a,b,ans=0,tempx,tempy,length=0;
    cin>>n>>s>>a>>b;
    int apples[5000]={0};//每个苹果需要的力气
    for(int i=0;i<n;i++){
        cin>>tempx>>tempy;
        if(tempx>a+b)continue;//1 出口 2 操作 3 变量更新
        apples[length++]=tempy;
    }
    sort(apples,apples+length);//要求写排序算法 最好不用
    for(int i=0;i<length;i++){
        if(s-apples[i]<0)break;
        s-=apples[i];
        ans++;
    }
    cout << ans<< endl;
    return 0;
}

P1618 三连击(升级版)

题目描述

将 1,2,…,9 共 99 个数分成三组,分别组成三个三位数,且使这三个三位数的比例是 A:B:C,试求出所有满足条件的三个三位数,若无解,输出 No!!!。

//感谢黄小U饮品完善题意

输入格式
三个数, A,B,C。

输出格式
若干行,每行 3 个数字。按照每行第一个数字升序排列。

样例

输入 #1复制
1 2 3

输出 #1复制
192 384 576
219 438 657
273 546 819
327 654 981

说明/提示
保证 A<B<C。

笔记

dfs 回溯法

代码
#include <iostream>
using namespace std;

int a,b,c,A,B,C,ans=0;
int result[9]={0},used[9]={0};

void dfs(int count){
    //出口
    if(count==9){
        a=result[0]*100+result[1]*10+result[2];
        b=result[3]*100+result[4]*10+result[5];
        c=result[6]*100+result[7]*10+result[8];
        if(a*B==b*A&&a*C==c*A) //  if(a/A*B==b&&a/A*C==c) 存在不能整除现象不准确
        {
            cout<<a<<" "<<b<<" "<<c<<endl;
            ans++;
        }
    }
    //入口
    for(int i=0;i<9;i++){
        if(used[i]==0){
            used[i]=1;
            result[count]=i+1;
            dfs(count+1);
            used[i]=0;
        }
    }
}

int main()
{
    cin>>A>>B>>C;
    dfs(0);
    if(ans==0)cout<<"No!!!"<<endl;
    return 0;
}

P1579 哥德巴赫猜想(升级版)

题目描述

1742年6月7日哥德巴赫写信给当时的大数学家欧拉,正式提出了以下的猜想:任何一个大于9的奇数都可以表示成3个质数之和。质数是指除了1和本身之外没有其他约数的数,如2和11都是质数,而6不是质数,因为6除了约数1和6之外还有约数2和3。需要特别说明的是1不是质数。

这就是哥德巴赫猜想。欧拉在回信中说,他相信这个猜想是正确的,但他不能证明。

从此,这道数学难题引起了几乎所有数学家的注意。哥德巴赫猜想由此成为数学皇冠上一颗可望不可及的“明珠”。

题目描述
现在请你编一个程序验证哥德巴赫猜想。

先给出一个奇数n,要求输出3个质数,这3个质数之和等于输入的奇数。

输入格式
仅有一行,包含一个正奇数n,其中9<n<20000

输出格式
仅有一行,输出3个质数,这3个质数之和等于输入的奇数。相邻两个质数之间用一个空格隔开,最后一个质数后面没有空格。如果表示方法不唯一,请输出第一个质数最小的方案,如果第一个质数最小的方案不唯一,请输出第一个质数最小的同时,第二个质数最小的方案。

样例

输入 #1复制
2009

输出 #1复制
3 3 2003

笔记
  • 判断质数。大于6的质数除6的余数都是1或5。若余数是0或2或4,则该数可被2整除;若余数是3,则该数可被3整除,不是质数。
	//判断质数模板,剪枝
	bool isPrime(int n){
		if(n<=1) return false;
		if(n==2||n==3) return true;
		if(n%6==1||n%6==5) return true; 
		for(int i=2;i*i<=n;i++){	//巧妙的把 2 3 跳过循环,直接true 
			if(n%i==0) return false;
		}
		return true;
	}
代码
#include<iostream>
#include<algorithm>
#include<string>
#include<map>
using namespace std;

bool isPrime(int n){
	if(n<=1) return false;
	if(n==2||n==3) return true;
	if(n%6==1||n%6==5) return true; 
	for(int i=2;i*i<=n;i++){	//巧妙的把 2 3 跳过循环,直接true 
		if(n%i==0) return false;
	}
	return true;
}

int main(){
	int n;
	cin>>n;
	for(int i=2;i<n;i++){
		if(isPrime(i)){
			for(int j=i;j<n;j++){
				if(isPrime(j) && isPrime(n-i-j)){
					cout<<i<<" "<<j<<" "<<n-i-j;
					return 0;
				}
			}
		}
	} 
	return 0;
} 


P2089 烤鸡

题目描述

猪猪 Hanke 得到了一只鸡。

题目描述
猪猪 Hanke 特别喜欢吃烤鸡(本是同畜牲,相煎何太急!)Hanke 吃鸡很特别,为什么特别呢?因为他有 10 种配料(芥末、孜然等),每种配料可以放 1 到 3 克,任意烤鸡的美味程度为所有配料质量之和。

现在, Hanke 想要知道,如果给你一个美味程度 n ,请输出这 10 种配料的所有搭配方案。

输入格式
一个正整数 n,表示美味程度。

输出格式
第一行,方案总数。

第二行至结束,10 个数,表示每种配料所放的质量,按字典序排列。

如果没有符合要求的方法,就只要在第一行输出一个 0。

样例

输入 #1复制
11

输出 #1复制
10
1 1 1 1 1 1 1 1 1 2
1 1 1 1 1 1 1 1 2 1
1 1 1 1 1 1 1 2 1 1
1 1 1 1 1 1 2 1 1 1
1 1 1 1 1 2 1 1 1 1
1 1 1 1 2 1 1 1 1 1
1 1 1 2 1 1 1 1 1 1
1 1 2 1 1 1 1 1 1 1
1 2 1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1 1 1

说明/提示
对于 100%100% 的数据,n \leq 5000n≤5000。

笔记
  • 需要先保存下来,最后再输出
代码
#include<iostream>
#include<algorithm>
#include<string>
#include<map>
using namespace std;

int n;
int rst[10],used[10],ans=0;
int rsts[10000][10];
void dfs(int count,int total){
	if(count==10){
		if(total==n){
			for(int i=0;i<10;i++) rsts[ans][i]=rst[i];
			ans++;
		}
	}
	else if(total>=n) ;
	else 
		for(int i=1;i<=3;i++){
				rst[count]=i;
				dfs(count+1,total+i);
		}
}

int main(){
	cin>>n;
	dfs(0,0);
	cout<<ans<<endl;
	for(int i=0;i<ans;i++){
		for(int j=0;j<10;j++)cout<<rsts[i][j]<<" ";
		cout<<endl;
	}
	return 0;
} 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值