【拓展歐幾里得】渡河(2022.5.21)
阿新 • • 發佈:2022-05-24
上題目!
題目
2.1 題目描述
現在有 N 名遊客需要渡河到對岸,但是島上只有兩艘船,第一艘船可以容納 n1 名遊客,第二艘船可以容納 n2 名遊客,為了不浪費位置,船長要求每次必須坐滿才能出發。現在已知使用第一艘船運輸一趟需要花費 c1,使用第二艘船運輸一趟需要花費 c2,問最小總花費。
2.2 輸入格式
第一行為一個整數 T,表示資料組數;
接下來T 行,每行五個整數 N, n1, c1, n2, c2,含義如題意所述。
2.3 輸出格式
輸出T 行對應T 組資料的答案,每行輸出兩個整數m1 和 m2 分別表示總花費最小時第
一艘船和第二艘船的運輸趟數,若無解則輸出“No solution”。當有解時,保證最優解唯一。
2.4 樣例輸入
2
43 3 1 4 2
40 9 5 12 5
2.5 樣例輸出
13 1
No solution
2.6 資料範圍與約定
對於前30%的資料 N≤100;
對於100%的資料,1≤T≤10000,1≤N,c1,c2,n1,n2≤2*109。
解思
拓歐跑一遍求最優通解(x,y大於零且價值最大的船對應的次數最大)即可
上程式碼
點選檢視程式碼
#include<bits/stdc++.h> using namespace std; #define int long long inline int read(){ int f=1,j=0;char w=getchar(); while(w>'9'||w<'0'){ if(w=='-')f=-1; w=getchar(); } while(w>='0'&&w<='9'){ j=(j<<3)+(j<<1)+w-'0'; w=getchar(); } return f*j; } int t; int extend_gcd(int a,int b,int &x,int &y){ if(b==0){ x=1;y=0; return a; } int d=extend_gcd(b,a%b,x,y); int tmp=x; x=y; y=tmp-(a/b)*y; return d; } int n,x,y,c1,c2,a,b; signed main(){ //freopen("river.in","r",stdin); //freopen("river.out","w",stdout); t=read(); while(t--){ int use=0; n=read();a=read();c1=read();b=read();c2=read(); if(a*c2<=b*c1)swap(a,b),use=1; int d=extend_gcd(a,b,x,y); if(n%d!=0){ printf("No solution\n"); continue; } x*=n/d;y*=n/d; int tag=a/d,k; if(y<0){ k=abs(y)/tag; if(y+k*tag<0)k++; y+=tag*k; x-=tag*b/a*k; } else{ k=y/tag; y-=tag*k; x+=tag*b/a*k; } if(x<0||y<0)printf("No solution\n"); else if(!use)printf("%lld %lld\n",x,y); else printf("%lld %lld\n",y,x); } return 0; } /* 2 43 3 1 4 2 40 9 5 12 5 1 1 5 1000 7 1 */