蓝桥杯刷题(一)

1.分巧克力

题目链接:http://lx.lanqiao.cn/problem.page?gpid=T441

题解:一看就知道只是一道二分题,因此思路就很好办了,二分区间【1,100000】,

然后进行判断是否分出的巧克力数大于等于K,若大于等于K就将L=mid

否则R=mid-1,最终的答案就是L。需要注意的是h和w不能盲目的根据面积去分巧克力,应该分别用(h/num)*(w/num)这样算出来的才是正确的巧克力数

代码:

#include<iostream>
using namespace std;
const int N=100010;
int n,k;
int h[N],w[N];

bool check(int num)
{
    int ans=0;
    for(int i=0;i<n;i++)
        ans+=(h[i]/num)*(w[i]/num);
    if(ans>=k)
        return true;
    else
        return false;
}

int main()
{
    int i,j;
    cin>>n>>k;
    for(i=0;i<n;i++)
        cin>>h[i]>>w[i];
    int l=1,r=100000,mid=0;
    while(l<r)
    {
        mid=(l+r+1)>>1;
        if(check(mid))
            l=mid;
        else
            r=mid-1;
    }
    cout<<l;
    return 0;
}

 

2.日期问题

题目:http://lx.lanqiao.cn/problem.page?gpid=T443

题解:这道题可以用枚举来做,数据范围不大,可以用数据范围从【19600101,20591231】

分别去除对应的year,month,day进行判断,首先判断是否为合法日期,在判断能否和数据对应上

在判断日期合法时需要注意的细节有:day==0||month==0记得要判断,其次就是平年和闰年的2月的日期要注意

代码:

#include<iostream>
#include<cstdio>
using namespace std;
int months[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};

bool check(int year,int month,int day)
{
    if(day==0||month==0||month>12)
        return false;
    if(month!=2&&day>months[month])
        return false;
    if(month==2)
    {
        int k=0;
        if(year%4==0&&year%100!=0||year%400==0)
            k=1;
        if(day>28+k)
            return false;
    }
    return true;
}

int main()
{
    int i,j,data,a,b,c;
    int year,month,day;
    scanf("%d/%d/%d",&a,&b,&c);
    for(data=19600101;data<=20591231;data++)
    {
        year=data/10000;month=(data%10000)/100;day=data%100;
        if(check(year,month,day))
        {
            if(year%100==a&&month==b&&day==c||
               month==a&&day==b&&year%100==c||
               day==a&&month==b&&year%100==c)
               {
                   printf("%d-%02d-%02d\n",year,month,day);
               }
        }
    }
    return 0;
}

 

3.包子凑数

题目:http://lx.lanqiao.cn/problem.page?gpid=T440

题解:这道题有两个难点,其一是范围:最大到多少之后就都能得到,100笼每笼最多100个,因此封顶范围10000;

其二判断何时为INF,当所有包子的最小公约数不为1时,就有无限个凑不出来。

对于有限个凑不出来的数,我们用dp来进行解决。

dp[n],代表n个包子能否凑出来,状态转移为dp[n-a[i]]是否能凑出来,如果可以,那么他也能凑出来

因此外层循环每笼包子的个数,内层循环从1-MAXN,来进行便利所有包子数

最后计算没能凑出包子的个数,即可。

代码:

#include<iostream>
using namespace std;
const int N=10010;
int n;
int a[110];
bool f[N+10];
int gcd(int a,int b)
{
    return b==0?a:gcd(b,a%b);
}

int main()
{
    int i,j,k=0;
    cin>>n;
    for(i=0;i<n;i++)
    {
        cin>>a[i];
        k=gcd(k,a[i]);
    }
    if(k!=1)
    {
        cout<<"INF";
    }
    else
    {
        f[0]=true;
        for(i=0;i<n;i++)
        {
            for(j=a[i];j<=N;j++)
                f[j]|=f[j-a[i]];
        }
        int ans=0;
        for(i=1;i<=N;i++)
        {
            if(f[i]==false)
                ans++;
        }
        cout<<ans;
    }
    return 0;
}

 

posted @ 2020-08-10 22:51  清风紫雪  阅读(727)  评论(0编辑  收藏  举报