1. 程式人生 > >UVA571Jugs題解--簡單數論(其實是瞎搞)

UVA571Jugs題解--簡單數論(其實是瞎搞)

倒水 blog 翻譯 emp += 非負數 algo system line

題目鏈接

https://cn.vjudge.net/problem/UVA-571

分析

剛做了道倒水問題的題想看看能不能水二倍經驗,結果發現了這道題

題意翻譯:https://www.cnblogs.com/devymex/archive/2010/08/04/1792288.html

設A容量\(x\),B容量\(y\)

我們把將水倒入A視為\(+x\),將倒空B視為\(-y\),若A滿,就倒入B視為\(-x\)

由於\(a,b\)是互質的,根據裴蜀定理一定有\(x,y\)保證有\(ax+by=gcd(a,b)=1\),又因為\(y>=c>=x>=0\)那麽也就保證了一定存在非負整數\(x\)和一個整數\(y\)

使得\(ax+by=c\).

於是一開始我的思路是運用擴展\(GCD\)求出一組解後將\(x\)轉化為一個非負數解.然後按步驟模擬就好了

然而在我寫模擬步驟時忽然發現完全不用擴歐啊,我們的模擬過程其實就是:

  • 若A空,則將A倒滿

  • 若B滿,將B倒空

  • 若A滿,將A中水倒入B中

由於題目要求輸出一種解就好了於是我們直接模擬就好了,至於為什麽會這樣,我好像還找不到較為嚴謹的數學證明

代碼

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <vector>
#define ll long long 
#define ri register int
using std::min;
using std::max;
using std::swap;
template <class T>inline void read(T &x){
    x=0;int ne=0;char c;
    while(!isdigit(c=getchar()))ne=c==‘-‘;
    x=c-48;
    while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
    x=ne?-x:x;return ;
}
int ex_gcd(int a,int b,int x,int y){
    if(!b){
        x=1,y=0;
        return a;
    }
    int d=ex_gcd(b,a%b,x,y);
    int z=x;x=y,y=z-(a/b)*y;
    return d;
}
int a,b,c;
int main(){
    int x,y,lef;
    int bot[3];
    while(scanf("%d %d %d",&a,&b,&c)!=EOF){
        //int d=ex_gcd(a,b,x,y);
        bool flag=1;
        if(b==c){
            puts("fill B");
            puts("success");
            flag=0;
        }
        bot[1]=bot[2]=0;
        //if(x>0){
            while(1&&flag){
                if(bot[2]==c){
                    puts("success");
                    break;
                }
                if(!bot[1]){
                    bot[1]=a;
                    puts("fill A");
                }
                else if(bot[2]==b){
                    puts("empty B");
                    bot[2]=0;
                }
                else if(bot[1]){
                    lef=b-bot[2];
                    if(lef<bot[1]){
                        bot[1]-=lef;
                        bot[2]+=lef;
                    }
                    else {                  
                        bot[2]+=bot[1];
                        bot[1]=0;
                    }
                    puts("pour A B");
                }
                //printf("%d %d\n",bot[1],bot[2]);
                //system("PAUSE");
            }
        //}
        /*else{
            int k=(-c*x)/b+1;
            x=c*x+k*b,y=c*y-k*a;
        }*/
    }
    return 0;
}

UVA571Jugs題解--簡單數論(其實是瞎搞)