• code+第四次网络赛div2


    T1 组合数问题:

    用k个不完全相同的组合数表示一个数n。

    用k-1个1和一个n-k+1表示即可。

     1 #include<cstdio>
     2 using namespace std;
     3 int x,k;
     4 int main()
     5 {
     6     scanf("%d%d",&x,&k);
     7     for (int i=1;i<k;i++) printf("%d %d
    ",i,0);
     8     printf("%d %d
    ",x-k+1,1);
     9     return 0;
    10 } 

    T2 喵呜:

    问从第x棵树的y高度,跳到第1棵或第n棵树的1或h高度,最少跳跃次数。

    跳跃有两种:往左或往右跳a棵树,每次可以往上跳b高度,或往下跳b高度。不能出界。

    如果可以跳出界,那么之后一定会跳回正常范围。所以可以证明在跳跃次数一定时必然可构造出不出界的方案。

    然后对于四种方案讨论一下:设跳跃距离=k*a,跳跃高度差=g*b。当k>g时,设x为向上跳的次数,x-(g-x)=k,所以x=(k+g)/2,所以只要(k+g)%2=0,x就有整数解。

    该方案的最小跳跃次数取max(k,g)。

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 typedef long long ll;
     5 const ll inf=1ll<<60;
     6 ll read()
     7 {
     8     ll x=0;char ch=getchar();
     9     while (ch<'0'||ch>'9') ch=getchar();
    10     while ('0'<=ch&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    11     return x;
    12 }
    13 ll n,h,x,y,a,b,Min;
    14 void solve(ll k,ll g)
    15 {
    16     if ((k+g)%2==0) Min=min(Min,max(k,g));
    17 }
    18 int main()
    19 {
    20     int T=read();
    21     while (T--)
    22     {
    23         n=read();h=read();x=read();y=read();a=read();b=read();
    24         if (abs(x-1)%a!=0&&abs(x-n)%a!=0||abs(y-1)%b!=0&&abs(y-h)%b!=0) {puts("-1");continue;}
    25         Min=inf;
    26         if (abs(x-1)%a==0&&abs(y-1)%b==0) solve(abs(x-1)/a,abs(y-1)/b);
    27         if (abs(x-1)%a==0&&abs(y-h)%b==0) solve(abs(x-1)/a,abs(y-h)/b);
    28         if (abs(x-n)%a==0&&abs(y-1)%b==0) solve(abs(x-n)/a,abs(y-1)/b);
    29         if (abs(x-n)%a==0&&abs(y-h)%b==0) solve(abs(x-n)/a,abs(y-h)/b);
    30         if (Min==inf) puts("-1");else printf("%lld
    ",Min);
    31     }
    32     return 0;
    33 }

    注意&&不要手滑写成||。

    T3 白金元首与七彩魔法:

    给你一个色盘,求两个点之间的一条线段上的所有点最大的亮度值(计算方式略)。

    计算一下线段的斜率,然后用微分的思想算出顶点在线段上的直角三角形的斜边长和tan。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cmath>
     4 using namespace std;
     5 const double pi=acos(-1);
     6 int T,a[3],r[3];
     7 double Max,k,b,x[3],y[3];
     8 double calc(double r,double g,double b)
     9 {return 0.3*r+0.59*g+0.11*b;}
    10 double solve(double a,double r)
    11 {
    12     if (a<0) a+=360;
    13     int h=a/60;
    14     double f=a/60.0-h,p=1-r,q=1-f*r,t=1-(1-f)*r;
    15     if (h==0) t=calc(1,t,p);
    16     if (h==1) t=calc(q,1,p);
    17     if (h==2) t=calc(p,1,t);
    18     if (h==3) t=calc(p,q,1);
    19     if (h==4) t=calc(t,p,1);
    20     if (h==5) t=calc(1,p,q);
    21     return t;
    22 }
    23 int main()
    24 {
    25    scanf("%d",&T);
    26    while (T--)
    27    {
    28          scanf("%d%d%d%d",&a[1],&r[1],&a[2],&r[2]);
    29          for (int i=1;i<=2;i++)
    30          {
    31                double g=a[i]/180.0*pi;//math库中的三角函数参数是弧度制
    32               x[i]=cos(g)*r[i]/100.0;
    33               y[i]=sin(g)*r[i]/100.0;
    34           }
    35           x[2]-=x[1];y[2]-=y[1];Max=0;
    36           for (int i=0;i<=100000;i++)//切割
    37           { 
    38              double X=x[1]+(double)i/100000.0*x[2];
    39              double Y=y[1]+(double)i/100000.0*y[2];
    40              Max=max(Max,solve(atan2(Y,X)/pi*180,sqrt(X*X+Y*Y)));
    41           }
    42          printf("%.4lf
    ",Max);
    43    }
    44    return 0;    
    45 } 

    注意不要把double开成int。

    T4 组合数问题2:

    求k个组合数的最大和,选取的每个组合数参数<=n且不完全相同。对1e9+7取模。

    用一个大根堆维护组合数的大小。类似bfs从第n层中间那个往上方两个和左右扩展。

    利用组合数的单调性还可以优化。

    特技:用lgammal(x+1)-lgammal(y+1)-lgammal(x-y+1)可以比较出组合数的大小,避免卡精度。(这个东西好像是处理阶乘的log)

     1 #include<bits/stdc++.h> 
     2 using namespace std;
     3 typedef long long ll;
     4 const int mod=1e9+7;
     5 const int N=1000005;
     6 struct node{
     7     double x,y;
     8     node(double A,double B) {x=A;y=B;}
     9 };
    10 double calc(node A)
    11 {return lgammal(A.x+1)-lgammal(A.y+1)-lgammal(A.x-A.y+1);}
    12 struct cmp{
    13     bool operator () (const node &A,const node &B)
    14     {return calc(A)<calc(B);}
    15 };
    16 priority_queue<node,vector<node>,cmp> p;
    17 int n,k,ans,jc[N],inv[N];
    18 map<int,int> mp[N];
    19 void init()
    20 {
    21     jc[0]=jc[1]=inv[0]=inv[1]=1;
    22     for (int i=2;i<=n;i++) jc[i]=(ll)jc[i-1]*i%mod,inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod;
    23     for (int i=2;i<=n;i++) inv[i]=(ll)inv[i-1]*inv[i]%mod;
    24 }
    25 int c(int n,int m) {return (ll)jc[n]*inv[m]%mod*inv[n-m]%mod;}
    26 int main()
    27 {
    28     scanf("%d%d",&n,&k);init();
    29     p.push(node(n,n/2));mp[n][n/2]=1;
    30     for (int i=1;i<=k;i++)
    31     {
    32         node now=p.top();p.pop();int x=now.x,y=now.y;
    33         int v=c(x,y);
    34         ans=((ll)ans+v)%mod;
    35         if (x>=1&&x-1>=y&&!mp[x-1][y]) p.push(node(x-1,y)),mp[x-1][y]=1;//注意边界限制!
    36         if (x>=1&&y>=1&&!mp[x-1][y-1]) p.push(node(x-1,y-1)),mp[x-1][y-1]=1;
    37         if (y>=1&&!mp[x][y-1]) p.push(node(x,y-1)),mp[x][y-1]=1;
    38         if (y+1<=x&&!mp[x][y+1]) p.push(node(x,y+1)),mp[x][y+1]=1;
    39     }
    40     printf("%d
    ",ans);
    41     return 0;
    42 }

    注意不要把取了模的东西扔进堆里比较。

  • 相关阅读:
    C# 控制反转(IOC: Inverse Of Control) & 依赖注入(DI: Independence Inject)
    英语常见短语汇总001
    ASP.Net Web.config 中引用外部config文件
    CSS样式汇总
    RSA非对称加密算法
    排序算法【2】——快速排序
    cmake引入boost
    boost之algorithm
    tar命令
    欧拉定理
  • 原文地址:https://www.cnblogs.com/Scx117/p/8690386.html
Copyright © 2020-2023  润新知