大家好,我是小黄呀。
@Time:2020/7/16 21:00-22:00
@Host:牛客网
位数求和
题目大意
求所有长度为n
的数中,各个 位
上的数字之和为m
的这些数的 和
。
题目虽然简短,还是得认真读两遍。
思路分析(暴力)
- 首先要表示长度为
n
的所有数,这里用一个[ pow(10,n-1),pow(10,n) )
就可以表示范围了。 - 然后就是要求一个数的
位数之和
,这里我写了一个sum1
函数来求,想必大家都会(0.0) - 然后暴力解法,直接遍历范围内的所有数,符合的话就加上,最后输出。
具体代码
class Solution {
public:
//求位数之和
long long sum1(long long A)
{
long long DA=0;
while(A!=0)
{
int temp=A%10;
DA+=temp;
A=A/10;
}
return DA;
}
//暴力求解
long long sum(int n,int m)
{
long long len1=pow(10,n-1);
//cout<<len1<<endl;
long long len2=pow(10,n);
//cout<<len2<<endl;
long long cnt=0;
while(len1<len2)
{
long long len3=sum1(len1);
if((int)len3==m)
cnt+=len1;
//cout<<cnt;
len1++;
}
return cnt;
}
};
牛牛晾衣服(POJ3104)
这道题大体与POJ3104类似,传送门
题目大意
有n
件带水的衣服,在数组vector<int>& a
给出了每件衣服带的水份,定义了两种干燥衣服的方式。
- 自然烘干:每分钟衣服自然烘干
1
滴水 - 烘干机:每分钟可以烘干
k
滴水,但烘干机每次只能放一件衣服,并且烘干机工作的时候,其他衣服仍然可以进行自然烘干。
最终要求最少需要多少时间(分钟为单位)把衣服全部烘干。
思路分析
- 暴力解法易超时,利用二分法进行判断。
- 当
k=1
时,特判,即每分钟最多烘干1
滴水,找出最大值、 - 当
k>1
时,首先,对vector
进行排序,得到最大元素,找出水份最多的衣服;然后利用二分法的思想,构造了一个check
函数来与中值进行比较,不断缩小范围,直至得到结果。 - 在
check
函数中,x
用于查找最短时间,假设在x
的时间内所有衣服一直在自然风干,则如果出现a[i]>x
,则说明有多余的水份需要烘干机来烘干。 - 而对于每一个
a[i]
,一定存在一个总时间m
,使得a[i]=(m-n)+n*k
,其中n
即为需要烘干机使用的次数,n=(a[i]-m)/(k-1)
,这里由于n
不满一次要当做一次,因此用celi
函数进行向上取整。将每一个a[i]
所需时间n
相加,即为总的烘干机时间sum
check
函数的判定条件方式为:若sum<=mid
,说明mid
时间满足烘干所有衣服,需要向下缩小范围;若sum>mid
,说明时间不够,需要向上缩小范围。
具体代码
typedef long long ll;
bool check(ll x,int n,vector<int>& a,int k)
{
ll sum=0;
for(int i=0;i<n;i++)
{
if(a[i]>x)
{
sum +=(ceil((a[i]-x)*1.0/(k-1)));
}
}
if(sum>x)
return 0;
else
return 1;
}
int solve(int n, vector<int>& a, int k) {
sort(a.begin(),a.end());
ll l = 1;
ll r = a[n-1];
ll ans=0;
if(k==1)
return (int)r;
else
{
while(l<=r)
{
ll mid=(l+r)/2;
if(check(mid,n,a,k)==1)
{
ans=mid;
r=mid-1;
}
else
l=mid+1;
}
return ans;
}
}