2101 - 枚举-练习-美食

2101 - 枚举-练习-美食

c++刷题 超能力编程

在这里插入图片描述
在这里插入图片描述

唯一提示:简单dfs

还是提示一下吧:==对于每种食材都有取和不取两种情况,全都枚举并返回最终结果取最小值即可,注意题目要求不能一种食材都不要!!==这题方法很多

直接上代码:

f1:

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cmath>
#include <iostream>
using namespace std;

int n;
bool used[20];
struct S
{
    int a = -1, b = -1;
}s[20];

int dfs(int pos)
{
    if(s[pos].a != -1)
    {
        used[pos] = true;
        int y = dfs(pos + 1);
        used[pos] = false;
        int n = dfs(pos + 1);
        return min(y, n);
    }else
    {
        bool bad = true;
        int suan = 1;
        int ku = 0;
        for(int i = 0; i < n; i++)
            if(used[i])
            {
                suan *= s[i].a;
                ku += s[i].b;
                bad = false;
            }
        if(bad)
            return 1000000001;
        else
            return abs(suan - ku);
    }
}

int main()
{
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> s[i].a >> s[i].b;
    s[n].a = -1;

    printf("%d\n", dfs(0));

    return 0;
}

f2:

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int M=15;//养成良好习惯
int a[M],b[M],n,ans=0x7fffffff;
//ans初始化为最大值
void dfs(int i,int x,int y){
//i是表示目前的配料编号,x为酸度,y为甜度
    if(i>n){
        //注意,必须大于n才表示全部搜完
        if(x==1&&y==0)return;
        //判断清水的情况
        ans=min(abs(x-y),ans);
        //更新ans
        return;
    }
    //分两种情况搜索:1添加 2不添加
    dfs(i+1,x*a[i],y+b[i]);
    dfs(i+1,x,y); 
    //这题无需回溯,不明白为何有些题解居然还用全局变量,非得回溯-_-||
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&a[i],&b[i]);
        //读入,用cin太慢了
    }
    dfs(1,1,0);
    printf("%d\n",ans);
    return 0;
}

f3:

#include <iostream>
#include <cmath>
using namespace std;

int n, s[15], b[15], ans=1e9;

void dfs(int k, int ss, int bb) {
    if (k == n) {
        if (ss == 1 && bb == 0)
            return ;
        ans = min(abs(ss - bb), ans);
        return ;
    }
    dfs(k+1, ss*s[k], bb+b[k]);
    dfs(k+1, ss, bb);
}

int main() {
    cin >> n;
    for (int i=0; i<n; ++i)
        cin >> s[i] >> b[i];
    dfs(0, 1, 0);
    cout << ans << endl;
    return 0;
}

f4:

#include<cstdio>
#include<algorithm>//头文件,min和abs在algorithm中(STL大法好)!
struct perket//定义结构体
{
    int sour,sweet;//sour表示酸度,sweet表示甜度
}a[11];//配料
int s=1,w,ans=2147483646,n;//ans一开始开2147483647莫名RE,用2147483646就好了。。。。。。
long long ok;//ok表示所用配料数
inline void read(int &a)//这里详细解释一下快速读入,inline的作用为加快该函数所用时间,注意:若不止一个输入输出文件,则不可用inline!
{
    char c;//定义字符存储变量
    int k=1;a=0;//定义系数(初始为1)与所读入变量
    c=getchar();//读入字符
    while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();}//如果该字符不为数字,跳过该字符,注意:由于本题有负数,所以要加判断是否为-号,如为-号,系数变为-1
    while(c>='0'&&c<='9'){a=a*10+c-'0';c=getchar();}//如果该字符为数字,原数*10+该字符-‘0’,其实*10+是特别特别有用的一个东西,不在这里详细论述,以后有时间的话会专门发一篇文章来解释*10+与其作用
    a*=k;//原数乘上系数
}
inline void print(int a)//快速输出
{
    if(a>10)print(a/10);//如果当前该数超过10,输出除个位外部分
    putchar(a%10+'0');//输出个位
}
void DFS(int i)//DFS,i表示当前搜索到第i个配料
{
    if(i==n+1)return ;//如果全部搜索完毕,回溯
    s*=a[i].sour;//当前酸度乘上该配料酸度
    w+=a[i].sweet;//当前甜度加上该配料甜度
    ok++;//所用配料数+1
    ans=std::min(ans,abs(s-w));//更新答案,取原答案与甜酸度之差的最小值,有人说可以加一个特判:当ans=0时,直接输出!我没有这么做,因为个人感觉没啥用
    DFS(i+1);//向下继续搜索
    s/=a[i].sour;//当前酸度除以该配料酸度
    w-=a[i].sweet;//当前甜度减去该配料甜度
    ok--;//所用配料数-1
    //这里解释一下:递归之前改变的值,递归过后一定要改回原值,即使你不再向下搜索,这也是递归的基本特征之一!!!
    DFS(i+1);//向下继续搜索,这是为了保证答案的全面性
}
int main()
{
    read(n);
    for(int i=1;i<=n;i++){read(a[i].sour);read(a[i].sweet);}//输入,不解释
    DFS(1);//DFS,从第一种配料开始搜索
    print(ans);//输出答案
}

完美结束~

  • 15
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值