M - 非常可乐

https://vjudge.net/contest/402204#problem/M

大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。

Input

三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量,以"0 0 0"结束。

Output

如果能平分的话请输出最少要倒的次数,否则输出"NO"。

Sample Input

7 4 3
4 1 3
0 0 0

Sample Output

NO
3

Sponsor

代码:

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include<time.h>
using namespace std;
#define ll long long
const int mod=1e9+7;
const int maxn=1e3+10;
int n,m,s,t,ans;
bool vis[maxn][maxn];
struct node{
    int s1;
    int s2;
    int s3;
    int cnt;
}p;
queue<node>q;
void bfs()
{
    while(!q.empty())
    {
        q.pop();
    }
    p.s1=s;
    p.s2=0;
    p.s3=0;
    p.cnt=0;
    q.push(p);
    memset(vis,0,sizeof(vis));
    vis[s][0]=1;
    while(!q.empty())
    {
        p=q.front();
        q.pop();
        if(p.s1*2==s&&p.s2*2==s||(p.s1*2==s&&p.s3*2==s))
        {
            ans=p.cnt;
            break;
        }
        if(p.s2!=n)
        {
            if(p.s1!=0)//s->n
            {
                int k=min(n-p.s2,p.s1);
                if(vis[p.s1-k][p.s2+k]==0)
                {
                    vis[p.s1-k][p.s2+k]=1;
                    q.push({p.s1-k,p.s2+k,p.s3,p.cnt+1});
                }
            }
            if(p.s3!=0)//m->n
            {
                int k=min(n-p.s2,p.s3);
                if(vis[p.s1][p.s2+k]==0)
                {
                    vis[p.s1][p.s2+k]=1;
                    q.push({p.s1,p.s2+k,p.s3-k,p.cnt+1});
                }
            }
        }
        if(p.s1!=s)
        {
            if(p.s2!=0)//n->s
            {
                int k=p.s2;
                if(vis[p.s1+k][p.s2-k]==0)
                {
                    vis[p.s1+k][p.s2-k]=1;
                    q.push({p.s1+k,p.s2-k,p.s3,p.cnt+1});
                }
            }
            if(p.s3!=0)//m->s
            {
                int k=p.s3;
                if(vis[p.s1+k][p.s2]==0)
                {
                    vis[p.s1+k][p.s2]=1;
                    q.push({p.s1+k,p.s2,p.s3-k,p.cnt+1});
                }
            }
        }
        if(p.s3!=m)
        {
            if(p.s1!=0)//s->m
            {
                int k=min(m-p.s3,p.s1);
                if(vis[p.s1-k][p.s2]==0)
                {
                    vis[p.s1-k][p.s2]=1;
                    q.push({p.s1-k,p.s2,p.s3+k,p.cnt+1});
                }
            }
            if(p.s2!=0)//n->m
            {
                int k=min(m-p.s3,p.s2);
                if(vis[p.s1][p.s2-k]==0)
                {
                    vis[p.s1][p.s2-k]=1;
                    q.push({p.s1,p.s2-k,p.s3+k,p.cnt+1});
                }
            }
        }
    }
}
int main()
{

    while(~scanf("%d %d %d",&s,&n,&m))
    {
        if(s==0&&n==0&&m==0)
            break;
        if(s%2==1)
        cout<<"NO"<<endl;
        else
        {
            ans=0;
            bfs();
            if(ans==0)
                cout<<"NO"<<endl;
            else
                cout<<ans<<endl;
        }

    }
    return 0;
}

 

#include <bits/stdc++.h> using namespace std; struct anss { int a,b; }; bool cmp(int n,int m) { if(n.a!=m.a) { return n.a<m.a; } return n.b>m.b; } int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int n,m; cin>>n>>m; anss ans[200005]; for(int i = 1;i<=m;i++) { cin>>ans[i].a>>ans[i].b; } sort(ans[1],ans[m],cmp); return 0; } 题目描述 有一家神秘的可乐商店。这家商店不直接出售可乐,而是提供空可乐瓶与新瓶装可乐的兑换服务。 初始时,高桥君拥有 N N 瓶可乐。之后,他可以多次(包括零次)选择以下任意一种操作: 掉一瓶可乐:如果他当前有瓶装可乐,可以掉一瓶。这样,他拥有的瓶装可乐数量减少 1,空瓶数量增加 1。(如果他没有瓶装可乐,则不能执行此操作。) 兑换操作:选择一个整数 i i( 1 ≤ i ≤ M 1≤i≤M),用 A i A i ​ 个空瓶兑换 B i B i ​ 瓶新可乐和 1 张纪念贴纸。(如果当前空瓶数量不足 A i A i ​ ,则不能选择该 可选,则不能执行此操作。) 高桥君非常喜欢贴纸。请问,在他采取最优策略的情况下,最多能获得多少张贴纸? 初始时,他没有空瓶,也没有贴纸。 约束条件 1 ≤ N ≤ 10 18 1≤N≤10 18 1 ≤ M ≤ 2 × 10 5 1≤M≤2×10 5 1 ≤ B i < A i ≤ 10 18 1≤B i ​ <A i ​ ≤10 18 所有输入均为整数。 输入格式 输入从标准输入按以下格式给出: text N M A_1 B_1 A_2 B_2 ... A_M B_M 输出格式 输出一个整数,表示高桥君最多能获得的贴纸数量。 样例输入 1 text 5 3 5 1 4 3 3 1 样例输出 1 text 3 样例解释 1 高桥君可以按以下步骤操作: 初始有 5 瓶可乐掉 1 瓶可乐 5 次,得到 5 个空瓶。 选择 i = 2 i=2,用 4 个空瓶兑换 3 瓶可乐和 1 张贴纸。此时有 3 瓶可乐、1 个空瓶和 1 张贴纸。 掉 1 瓶可乐 3 次,得到 4 个空瓶。 再次选择 i = 2 i=2,用 4 个空瓶兑换 3 瓶可乐和 1 张贴纸。此时有 3 瓶可乐和 2 张贴纸。 掉 1 瓶可乐 3 次,得到 3 个空瓶。 选择 i = 3 i=3,用 3 个空瓶兑换 1 瓶可乐和 1 张贴纸。此时有 1 瓶可乐和 3 张贴纸。 最终,高桥君最多可以获得 3 张贴纸。 样例输入 2 text 3 3 5 1 5 1 4 2 样例输出 2 text 0 样例解释 2 高桥君只能掉初始的 3 瓶可乐,无法进行任何兑换操作。 样例输入 3 text 415 8 327 299 413 396 99 67 108 51 195 98 262 180 250 175 234 187 样例输出 3 text 11 解题思路 这是一个典型的贪心问题。我们需要找到最优的兑换顺序,使得高桥君能够获得最多的贴纸。关键在于每次选择“性价比”最高的兑换方式,即用最少的空瓶获得最多的可乐和贴纸。 具体步骤如下: 排序兑换选项:按照 A i − B i A i ​ −B i ​ 从小到大排序(即每次兑换后净消耗的空瓶数最少),这样可以在有限的空瓶下尽可能多地进行兑换。 模拟兑换过程:初始时,高桥君有 N N 瓶可乐和 0 个空瓶。每次尽可能多地可乐,积累空瓶,然后用空瓶兑换更多的可乐和贴纸,直到无法继续兑换为止。 计算最大贴纸数:在每次兑换时,计算当前可以进行的最大兑换次数,并累加贴纸数量。 扩写
07-20
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值