例如:A = 4 B = 0 K = 3
0000 -> 1110 -> 1001 -> 0100 -> 1111
需要的最少操作次數爲4
這個題的關鍵是理解A=10000,B=10000,K=548時,不需要貪心到134,而是在A=134+K的時候就可以進行兩次就可以了。
#include <iostream>
#include <queue>
using namespace std;
struct node{
int x,y,p;
node(int a,int b,int c):x(a),y(b),p(c){};
};
queue<node> fk;
int ft[100005]={0};
int k;
int BFS(){
int a,b;
while(!fk.empty()){
node fn=fk.front();
fk.pop();
while(fn.x>=k){
fn.p+=fn.x/k;
fn.x=fn.x%k;
}
if(fn.x==0){
return fn.p;
}
if((k+fn.x)%2==0 && fn.p>0 && fn.y>=2*k-(fn.x+k)/2)
return fn.p+1;
for(int i=1;i<=fn.x;i++){
if((fn.y+i)>=k){
a=fn.x+k-i-i;
b=fn.y-k+i+i;
if(a==0)
return fn.p+1;
if(ft[a]==0){
ft[a]=fn.p+1;
node fs(a,b,fn.p+1);
fk.push(fs);
}
}
}
}
return -1;
}
int main(){
int a,b,minp;
scanf("%d%d%d",&a,&b,&k);
if(a==0){
printf("0\n");
return 0;
}
int sum=a+b;
int ans=0;
while(a>=k){
ans+=a/k;
a=a%k;
}
if(a==0){
printf("%d\n",ans);
return 0;
}
node tmp(a,sum-a,ans);
fk.push(tmp);
ft[a]=ans;
minp=BFS();
printf("%d\n",minp);
return 0;
}
下面是大神的純數學做法,是考慮ABK的奇偶情況。
#include<iostream>
#include<cmath>
using namespace std;
int function(int A, int B, int K){
int remainder = A % K;
int count = A / K;
B += A - remainder;
if (A == 0 || remainder == 0)
;
else if ((remainder + B <= K) || (remainder % 2 == 1 && K % 2 == 0))
count = -1;
else if ((K + remainder) % 2 == 0 && count > 0 && B >= 2 * K - (remainder + K) / 2)
count++;
else if (remainder % 2 == 0)
count += 2 * ceil(remainder / double(2 * (B - K + remainder)));
else
count += 2 * ceil((K - remainder) / double(2 * (B - K + remainder))) + 1;
return count;
}
int main(){
int A, B, K;
cin >> A >> B >> K;
cout << function(A, B, K);
return 0;
}