习题日常第二十一练

1圆与三角形(题目链接

这个题是个公式题。通过(A+B+C)/2=90度,可以得出sinA*r之前的恒等于1,只要A等于90度即可得出最大。主要考察三角函数的化简。

 double r;
    scanf("%lf",&r);
    printf("%.2lf",r+1);

2字符串(题目链接

这个题是个不错的思维题。看过题解以后发现非常的巧妙。把所求问题转化在坐标中,开始状态为(0,0),总共走n+m步,如果当前位置选1,坐标加(1,1),如果选0,坐标加(1,-1)。因为有n个1,所以总的方案数为C(n+m,n)。而不满足的方案必定过y=-1这条线,根据对称性,则相当于从(0,-2)走到(n+m,n-m)则走(1,1)的情况为(n+1)种。非法的情况就有C(n+m,n+1)种,减去即可。中间还涉及一个费马小定理。代码如下。

#include<cmath>
#include <iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<vector>
#include<set>
#include<map>
#include<cstring>
#include<math.h>
#include<stack>
#include<algorithm>
#include<queue>
#include<bitset>
#include<sstream>
#define  ll long long int
const int mod=20100403;
using namespace std;
ll a[2100010];
ll mypow(ll x,ll y)
{
    ll ans=1;
    while(y)
    {
        if(y&1)
            ans=(ans*x)%mod;
        x=(x*x)%mod;
        y>>=1;
    }
    return ans;
}
int main()
{
    ios::sync_with_stdio(false);
    ll m,n,i,j,k;
    cin>>n>>m;
    if(n<m)
        cout<<0;
    else
    {
    a[1]=1;
    for(i=2;i<=n+m;i++)
    {
        a[i]=(a[i-1]*i)%mod;
    }
    ll ans1=(((a[n+m]*mypow(a[n],mod-2))%mod)*mypow(a[m],mod-2))%mod;
    ll ans2=(((a[n+m]*mypow(a[n+1],mod-2))%mod)*mypow(a[m-1],mod-2))%mod;
    ans1=(ans1-ans2)%mod;
    while(ans1<0)
        ans1+=mod;
    cout<<ans1;
    }
  return 0;
}

3逛画展(题目链接

这个题用了一种尺取的思想。从右边界开始拓展,直到拓展到把每个数字都吧包含进去了,再拓展左边界,直到去掉左边界的数字的区间不能包含所有数字,这时加上这个左边界构成的区间即为满足条件的区间,再看区间长度是否小于已知,以此维护左右边界。代码如下。

#include<cmath>
#include <iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<vector>
#include<set>
#include<map>
#include<cstring>
#include<math.h>
#include<stack>
#include<algorithm>
#include<queue>
#include<bitset>
#include<sstream>
#define  ll long long int
const int mod=20100403;
using namespace std;
int a[2100100],p[5010];
int main()
{
    /*ios::sync_with_stdio(false);*/
    int m,n,i,j,k,anl,anr,l=0,r;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        anr=0;
        anl=0;
        l=0;
    memset(a,0,sizeof(a));
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
    }
    i=0;
    k=0;
    r=0;
    memset(p,0,sizeof(p));
    while(k!=m)
    {
        p[a[i]]++;
        if(p[a[i]]==1)
        {
            k++;
        }
        i++;
    }
    while(p[a[l]]>1)
    {
       p[a[l++]]--;
    }
    anl=l;
    anr=i;
    while(i<n)
    {
       p[a[i]]++;
       i++;
       while(p[a[l]]>1)
       {
           p[a[l++]]--;
       }
        if(i-l<anr-anl)
        {
            anr=i;
            anl=l;
        }
    }
   printf("%d %d\n",anl+1,anr);
    }
  return 0;
}

4摆花(题目链接

这个题看起来不好做,但是实际用一个动态规划就能解决。具体见代码。

  cin>>n>>m;
    for(i=0;i<n;i++)
    cin>>a[i];
    memset(p,0,sizeof(p));
    p[0]=1;
    for(i=0;i<n;i++)
    {
         for(k=m;k>=1;k--)
        {
        for(j=1;j<=min(a[i],k);j++)
            {
                p[k]=(p[k]+p[k-j])%mod;
            }
        }
    }
    cout<<p[m];
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值