A.
简单的容斥原理,注意一些奇怪的大小问题即可。
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
int a,b,c,n;
cin>>a>>b>>c>>n;
if(c>a||c>b||c>a+b||a+b-c+1>n){
cout<<-1<<endl;return 0;
}
cout<<n-(a+b-c)<<endl;
return 0;
}
B.
贪心搞搞就可以了。
#include<cstdio>
#include<iostream>
#include<set>
#include<algorithm>
using namespace std;
int main()
{
int n,i,j,k;
double tar,ans=0;
cin>>n;
multiset<int>s;
for(i=1;i<=n;i++){
cin>>j;s.insert(j);ans+=j;
}
tar=n*4.5;
int cnt=0;
while(ans<tar){
ans+=(5-(*s.begin()));s.erase(s.begin());cnt++;
}
cout<<cnt<<endl;
return 0;
}
C.
注意到k越大时他能吃到的糖一定是越多 的,因此我们可以在此基础上对k进行二分,至于判断他能在这个情况下吃糖的数目,根据题意模拟即可。
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
long long n,x,y,z,L=0,R,k;
cin >> n;
R = n;
while (R - L > 1) {
k = (R + L) / 2;
x = n;y = 0;
while (x) {
z = min(x, k);
y += z;x -= z;
x -= x / 10;
}
if (2 * y >= n) R = k;
else L = k;
}
cout << R << endl;
return 0;
}
D.
明显可以动态规划来做,但是有些细节需要小心。首先,用f[i][j]表示到第i列时末尾这列放置的是第j种block时的最大可能数,那么f[i][j]可以从f[i-2]k以及f[i-1]k转移而来。同时需要注意初始化的问题,这一列的每种情况至少是上一列的所有情况的最大值(因为统计的是最大的和);
#include<cstdio>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int pos[3][105];
bool judge(int x,int type)//判断状态是否可放
{
if(type==1){
if(pos[