[CF1225C] p-binary
给定整数n,p,求最小的x使其满足
∑
i
=
1
x
(
2
k
+
p
)
=
n
\sum_{i=1}^{x}(2^k+p)=n
i=1∑x(2k+p)=n
其中k可以是任意的自然数。
输入格式:n,p(1<=n<=10^9,-1000<=p<=1000)
输出格式:
找不到这样的x输出-1,否则输出x。
样例:
input1:24 0 output:2
input2:24 1 output:3
分析:
这个题设最后的答案为t,原式可以展开,成为
(
2
k
1
)
+
(
2
k
2
)
.
.
.
+
(
2
k
t
)
+
t
p
=
n
(2^k1)+(2^k2)...+(2^kt)+tp=n
(2k1)+(2k2)...+(2kt)+tp=n
即
(
2
k
1
)
+
(
2
k
2
)
.
.
.
+
(
2
k
t
)
=
n
−
t
p
(2^k1)+(2^k2)...+(2^kt)=n-tp
(2k1)+(2k2)...+(2kt)=n−tp
刚好能被t个二进制表示。
如果n-tp<t,则无法表示,因为每个二进制最小为2^0=1,t个二进制最小是t。同时,t只可大不可小。因为t不能比n-tp的二进制的1个数少。
#include<bits/stdc++.h>
using namespace std;
int main(){
//freopen("pbinary.in","r",stdin);
//freopen("pbinary.out","w",stdout);
int n,p;
cin>>n>>p;
for(int i=0;i<=10000;i++){ //i为上述的t,即最后的答案。
int tmp=n-p*i,cnt=0;//tmp为上述的n-tp。
while(tmp){
cnt=cnt+tmp%2;
tmp=tmp/2;//一直短除法求二进制
}
if(cnt<=i && n-p*i){ //符合情况
cout<<i<<endl;
return 0;
}
}
cout<<-1<<endl;//不符合情况
return 0;
}
[CF1214A] Optimal Currency Exchange
Andrew参加了Olympiad of Metropolises,现准备回国,需要兑换货币。
现有如下面额的美元纸币:1,2,5,10,20,50,100,以及以下面额的欧元纸币:5,10,20,50,100,200(注意,不考虑500欧元纸币,因为在货币兑换窗口很难找到这种)。已知兑换1美元需要d卢布,1欧元需要e卢布,而Andrew有n卢布。
他可以兑换任意数量的美元和欧元(一种纸币可以兑换多次,可以美元和欧元混合),并且,他希望使兑换后手里剩余的卢布数尽可能少。请你写一个程序帮他解决问题(只需求出最小的剩余卢布数)。
输入格式:
3行,3个整数n,d,e
输出格式:
1行,最小剩余量
数据范围:
1<=n<=10^8
30<=d,e<=100
样例:
input1:100 60 70
output1:40
input2:410 55 70
output2:5
思路:我们看题不难发现,美元纸币的款项都是1块组成的,欧元纸币的款项都是5块钱组成的(倍数)。
那么先把钱全去买美元,然后再把剩下的钱买欧元就行了,最后剩下的钱,输出就行了
#include<bits/stdc++.h>
using namespace std;
int main(){
freopen("exchange.in","r",stdin);
freopen("exchange.out","w",stdout);
int n,d,e,ans=100000000;//100 60 70
cin>>n>>d>>e;
e=e*5;//350
for(int i=1;i<=n/d;i++){ //i=1
if(ans>(n-i*d)%e) ans=(n-i*d)%e;//ans=(100-1*60)%70 40%70
}
cout<<ans<<endl;
return 0;
}