• 牛客小白月赛20


    有一说一最近状态确实不太行,打了这么久还是停留在初等小白。

    A.斐波那契

    求斐波那契数列前n项的平方和。这是斐波那契数列面积的应用,就是求f[n] * f[n + 1],用俩次矩阵快速幂求得。o(logn)

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 typedef long long ll;
     6 
     7 const int N = 2;
     8 const ll mod = 1e9 + 7;
     9 
    10 ll n;
    11 
    12 ll temp[N][N], res[N][N];
    13 
    14 void muti(ll a[][N], ll b[][N], int n)
    15 {
    16     memset(temp, 0, sizeof(temp));
    17     for (ll i = 0; i < n; i ++)    
    18     {
    19         for (ll j = 0; j < n; j ++)
    20         {
    21             for (ll k = 0; k < n; k ++)
    22             {
    23                 temp[i][j] += (a[i][k] * b[k][j]) % mod;
    24             }
    25             temp[i][j] %= mod;
    26         }
    27     }
    28     for (ll i = 0; i < n; i ++)
    29         for(ll j = 0; j < n; j ++)
    30             a[i][j] = temp[i][j];
    31 }
    32 
    33 void Pow(ll a[][N], ll m, int n)
    34 {
    35     memset(res, 0, sizeof(res));
    36     for (ll i = 0; i < n; i ++) res[i][i] = 1;
    37     while(m)
    38     {
    39         if(m& 1) muti(res, a, n);
    40         muti(a, a, n);
    41         m >>= 1;
    42     }
    43 }
    44 
    45 int main()
    46 {
    47     scanf("%lld", &n);
    48     ll a[N][N];
    49     a[0][0] = 1, a[0][1] = 1, a[1][0] = 1, a[1][1] = 0;
    50     Pow(a, n, 2);
    51     ll ans1 = res[1][0];
    52     a[0][0] = 1, a[0][1] = 1, a[1][0] = 1, a[1][1] = 0;
    53     Pow(a, n + 1, 2);
    54     ll ans2 = res[1][0];
    55     printf("%lld
    ", ((ans1 % mod ) * (ans2 % mod)) % mod);
    56  } 
    View Code

    B.最大边长

    打的时候不知道为什么被这样的题卡了很久。假设x < y,那么在x 上只能存在一个正方形,y存在3个, 或者x存在两个, y存在两个。反之也成立。

     1 //#include<bits/stdc++.h>
     2 #pragma GCC optimize(2)
     3 #pragma G++ optimize(2)
     4 #include<map>
     5 #include<set>
     6 #include<cmath>
     7 #include<ctime>
     8 #include<queue>
     9 #include<stack>
    10 #include<cstdio>
    11 #include<random>
    12 #include<string>
    13 #include<vector>
    14 #include<cstring>
    15 #include<utility>
    16 #include<iostream>
    17 #include<algorithm>
    18 #include<functional>
    19 #include<unordered_map>
    20 #include<unordered_set>
    21 using namespace std;
    22  
    23 #define ios ios::sync_with_stdio(false)
    24 #define ll long long
    25 #define pa pair<int,int>
    26 #define mk make_pair
    27 #define sc(n) scanf("%d",&n)
    28 #define ss(s) scanf("%s",s)
    29 #define fo(i, a, b) for(int i = a; i <= b; i++)
    30 #define of(i, a, b) for(int i = a; i >= b; i--)
    31 #define mem(a, b) memset(a, b, sizeof a)
    32 #define copy(a,b) memcpy(a, b, sizeof b)
    33 #define pi acos(-1)
    34 #define input freopen("input.in", "r", stdin);
    35 #define output freopen("output.out", "w", stdout);
    36  
    37 const ll inf = 0x3f3f3f3f;
    38 const ll mod = 1e9 + 7;
    39 const ll N = 2e5 + 10;
    40 const ll M = 1e4 + 10;
    41 const double eps = 1e-10;
    42  
    43 using namespace std;
    44  
    45 int t, n;
    46  
    47 int main()
    48 {
    49     ll a, b, c;
    50     cin >> a >> b;
    51     ll ans = 0;
    52     if (a / 3 >= b)
    53         ans = max(ans, b);
    54     if (b / 3 >= a)
    55         ans = max(ans, a);
    56     if (b / 2 * 2 <= a)
    57         ans = max(ans, b / 2);
    58     if (a / 2 * 2 <= b)
    59         ans = max(ans, a / 2);
    60     cout << ans << endl;
    61     return 0;
    62 }
    View Code

    C.球的表面积

    做这题必须知道球冠的表面积公式2πRH, R为球半径,H为球冠的高。若两个球相离,则是面积相加。若包含关系,则输出较大的面积。若相加,就是俩个球冠的表面积被除去。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<string>
     6 #include<vector>
     7 #include<math.h>
     8 using namespace std;
     9 #define ll long long
    10 #define PI  3.1415926
    11 int main()
    12 {
    13    double x1,y1,z1,r1,x2,y2,z2,r2;
    14    scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&x1,&y1,&z1,&r1,&x2,&y2,&z2,&r2);
    15    double ans1=4*PI*r1*r1;
    16    double ans2=4*PI*r2*r2;
    17    double len=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
    18    if(len>=r1+r2)
    19    {
    20        printf("%.6lf
    ",ans1+ans2);
    21    }
    22    else if((len<r1+r2)&&(len>max(r1,r2)-min(r1,r2)))
    23    {
    24        double cosa=(r1*r1+len*len-r2*r2)/(2*r1*len*1.00000);
    25        double dis1=cosa*r1;
    26        double h1=r1-dis1;
    27        double s1=ans1-2*PI*r1*h1;
    28  
    29        double cosb=(r2*r2+len*len-r1*r1)/(2*r2*len*1.00000);
    30        double dis2=cosb*r2;
    31        double h2=r2-dis2;
    32        double s2=ans2-2*PI*r2*h2;
    33        printf("%.6lf
    ",s1+s2);
    34    }
    35    else if(len<=max(r1,r2)-min(r1,r2))
    36    {
    37        printf("%lf
    ",max(ans1,ans2));
    38    }
    39 }
    View Code

    D.3的倍数

    发现n很小,直接暴力。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 int n;
     6 char s[20][10010];
     7 
     8 int f[20][36];
     9 int res[36];
    10 int ans;
    11 
    12 bool check()
    13 {
    14     for (int i = 1; i <= 26; i ++)
    15     {
    16         if(res[i] % 3) return false;
    17     }
    18     return true;
    19 }
    20 
    21 void dfs(int u, int cnt)
    22 {
    23     if(u == n + 1)
    24     {
    25         if(check())
    26         ans = max(ans, cnt);
    27         return ;    
    28     }
    29     for (int j = 1; j <= 26; j ++) res[j] += f[u][j];
    30     dfs(u + 1, cnt + 1);
    31     for (int j = 1; j <= 26; j ++) res[j] -= f[u][j];
    32     dfs(u + 1, cnt);    
    33 }
    34 
    35 int main()
    36 {
    37     scanf("%d", &n);
    38     for (int i = 1; i <= n; i ++)
    39     {
    40         scanf("%s", s[i] + 1);
    41         int len = strlen(s[i] + 1);
    42         for (int j = 1; j <= len; j ++)
    43         {
    44             f[i][s[i][j] - 'A' + 1] ++;
    45         }
    46     }
    47     dfs(1, 0);
    48     cout << ans << endl;
    49  } 
    View Code

    E.区区区间

    这题明示线段是,但是本人因为最近学了分块,结果一直想要分块,结果自闭住。其实线段树比较好想,用lazy数组去维护区间最左端的值。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 typedef long long ll;
     6 
     7 const int N = 2e5 + 10;
     8 
     9 int n, m;
    10 ll a[N];
    11 ll sum[N << 2], lazy[N << 2];
    12 
    13 void pushup(int rt)
    14 {
    15     sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
    16 }
    17 
    18 void pushdown(int rt, int llen, int rlen)
    19 {
    20     if(lazy[rt])
    21     {
    22         lazy[rt << 1] = lazy[rt];
    23         lazy[rt << 1 | 1] = lazy[rt] + llen;
    24         sum[rt << 1] = 1ll * (lazy[rt] + lazy[rt] + llen - 1) * llen / 2;
    25         sum[rt << 1 | 1] = 1ll * (lazy[rt << 1 | 1] + lazy[rt << 1 | 1] + rlen - 1) * rlen / 2;
    26         lazy[rt] = 0;
    27     }
    28 }
    29 
    30 void build(int l, int r, int rt)
    31 {
    32     if(l == r)
    33     {
    34         sum[rt] =  a[l];
    35         lazy[rt] = 0;
    36         return ;
    37     }
    38     int mid = l + r >> 1;
    39     build(l, mid, rt << 1), build(mid + 1, r, rt << 1 | 1);
    40     pushup(rt);
    41 }
    42 
    43 ll query(int L, int R, int l, int r, int rt)
    44 {
    45     ll ans = 0;
    46     if(L <= l && R >= r)
    47     {
    48         return sum[rt];
    49     }
    50     int mid = l + r >> 1;
    51     pushdown(rt, mid - l + 1, r - mid);
    52     if(L <= mid) ans += query(L, R, l, mid, rt << 1);
    53     if(R > mid)     ans += query(L, R, mid + 1, r, rt << 1 | 1);
    54     return ans;
    55 }
    56 
    57 void update(int L, int R, int C,int l, int r, int rt)
    58 {
    59     if(L <= l && R >= r)
    60     {
    61         sum[rt] = 1ll * (r - l + 1) * (C - L + l + C - L + l + r - l) / 2;
    62         lazy[rt] = C - L + l;
    63         return ;
    64     }
    65     int mid = l + r >> 1;
    66     pushdown(rt, mid - l + 1, r - mid);
    67     if(L <= mid) update(L, R, C, l, mid, rt << 1);
    68     if(R > mid)     update(L, R, C, mid + 1, r, rt << 1 | 1);
    69     pushup(rt);
    70 }
    71 
    72 int main()
    73 {
    74     scanf("%d%d", &n, &m);
    75     for (int i = 1; i <= n; i ++)
    76         scanf("%lld", &a[i]);
    77     build(1, n, 1);
    78     while(m --)
    79     {    
    80         int op;
    81         scanf("%d", &op);
    82         if(op == 1)
    83         {
    84             int l, r, k;
    85             scanf("%d%d%d", &l, &r, &k);
    86             update(l, r, k, 1, n, 1);
    87         }
    88         else
    89         {
    90             int l, r;
    91             scanf("%d%d", &l, &r);
    92             printf("%lld
    ", query(l, r, 1, n, 1));
    93         }
    94     }    
    95  } 
    View Code

    F.进制转换

    用短除法。基本操作。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 int n, m, k;
     6 
     7 char s[2200];
     8 
     9 vector<int>a;
    10 
    11 int main()
    12 {
    13     scanf("%s", s + 1);
    14     scanf("%d%d", &m, &k);
    15     int len = strlen(s + 1);
    16     for (int i = len; i >= 1; i --)
    17     {
    18         if(s[i] >= '0' && s[i] <= '9')
    19         {
    20             a.push_back(s[i] - '0');
    21         }
    22         else if(s[i] >= 'a' && s[i] <= 'z')
    23         {
    24             a.push_back(s[i] - 'a' + 10);
    25         }
    26     }
    27     vector<int> res;
    28     while(a.size())
    29     {
    30         int t = 0;
    31         for (int i = a.size() - 1; i >= 0; i --)
    32         {
    33             a[i] += t * m;
    34             t = a[i] % k;
    35             a[i] /= k;
    36         }
    37         res.push_back(t);
    38         while(a.size() && !a.back()) a.pop_back();
    39     }
    40     reverse(res.begin(), res.end());
    41     string b_line;
    42         for (auto x : res )
    43         {
    44                if (x <= 9) b_line += char('0' + x);
    45             else b_line += char('a' + x - 10);
    46         }
    47         cout << b_line << endl;
    48 }
    View Code

    G.快乐风男

    求最长严格上升子序列字典序最小的。那么直接贪心,先二分求出每个a[i]应该出现在上升数组的哪个位置。然后对位置进行贪心。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const int N = 1e5 + 10;
     6 const int INF = 0x3f3f3f3f;
     7 
     8 int n;
     9 int a[N], cnt, f[N];
    10 
    11 int len[N], first[N];
    12 int ans[N];
    13 
    14 int main()
    15 {
    16     memset(f, 0x3f, sizeof(f));
    17     scanf("%d", &n);
    18     for (int i = 1; i <= n; i ++)
    19         scanf("%d", &a[i]);
    20     for (int i = 1; i <= n; i ++)
    21     {
    22         int t = lower_bound(f + 1, f + n + 1, a[i]) - f;
    23         if(f[t] == INF)
    24         {
    25             ++ cnt;
    26             f[t] = a[i];
    27             len[i] = t;
    28         }
    29         else
    30         {
    31             f[t] = a[i];
    32             len[i] = t;
    33         }
    34         if(first[len[i]] == 0) first[len[i]] = i;
    35     }
    36     printf("%d
    ", cnt);
    37     ans[cnt] = first[cnt];
    38     for (int i = first[cnt] - 1; i >= 1; i --)
    39     {
    40         if(a[i] < a[ans[len[i] + 1]])
    41         ans[len[i]] = i;
    42      }
    43     for(int i = 1; i <= cnt; i++)
    44     printf("%d%c", ans[i], i==cnt?'
    ':' ');
    45 } 
    View Code

    H.好点

    类似二位偏序,只要求右上角不存在的情况,那么按横坐标从小到大,从后往前开始记录,若它的纵坐标最大,其右上角一定不存在点。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn = 5e5 + 100;
     5 const int mod = 1e9 + 7;
     6 int n, m;
     7 struct node{
     8     int x, y;
     9     bool operator<(const node &a)const{
    10         return x < a.x;
    11     }
    12 }a[maxn],ans[maxn];
    13 int main(){
    14     cin >> n;
    15     for (int i = 1; i <= n; i++)
    16         scanf("%d%d", &a[i].x, &a[i].y);
    17     sort(a + 1, a + 1 + n);
    18     int my = -1e9-1;
    19     int num = 0;
    20     for (int i = n; i>= 1; i--){
    21         if (a[i].y > my){
    22             my = a[i].y;
    23             ans[++num].x = a[i].x;
    24             ans[num].y = a[i].y;
    25         }
    26     }
    27     sort(ans + 1, ans + 1 + num);
    28     for (int i = 1; i <= num; i++)
    29         cout << ans[i].x << " " << ans[i].y << endl;
    30     return 0;
    31 }
    View Code

    I.小小小马

    对于n <= 3 && m <= 3(除了n == 1 && m == 1)都不可行,其余都可行。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 typedef pair<int, int> PII;
     6 
     7 const int N = 2e3 + 10;
     8 
     9 int n, m; 
    10 
    11 bool st[N][N];
    12 
    13 
    14 int main()
    15 {    
    16     scanf("%d%d", &n, &m);
    17     if(n == 1 && m == 1)
    18     {
    19         puts("Yes");
    20         return 0;
    21     }
    22     if(n == 1 || m == 1)
    23     {
    24         puts("No");
    25         return 0;
    26     }
    27     if(n == 2 || m == 2)
    28     {
    29         puts("No");
    30         return 0;
    31     }
    32     if(n <= 3 && m <= 3)
    33     {
    34         puts("No");
    35         return 0;
    36     }
    37     puts("Yes");
    38     
    39  } 
    View Code

    J.dh的帽子

    典型的数位DP,一个上界一个下界。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 typedef long long ll;
     6 
     7 ll dp[32][2][2][2][2][2][2];
     8 int num1[32], num2[32];
     9 
    10 
    11 ll dfs(int len, bool lim1, bool lim2, bool lim3, bool im1, bool im2, bool im3)
    12 {
    13     if(len == -1) return 1;
    14     if(dp[len][lim1][lim2][lim3][im1][im2][im3] != -1) return dp[len][lim1][lim2][lim3][im1][im2][im3];
    15     ll ans = 0;
    16     int up1 = lim1 ? num2[len] : 1;
    17     int up2 = lim2 ? num2[len] : 1;
    18     int up3 = lim3 ? num2[len] : 1;
    19     int down1 = im1 ? num1[len] : 0;
    20     int down2 = im2 ? num1[len] : 0;
    21     int down3 = im3 ? num1[len] : 0;
    22     for (int i = 0; i <= up1; i ++)
    23         for (int j = 0; j <= up2; j ++)
    24             for (int k = 0; k <= up3; k ++)
    25                 {
    26                     if(i < down1 || j < down2 || k < down3) continue;
    27                     if((i ^ j ^ k) != (i | j | k)) continue;
    28                     ans += dfs(len - 1, lim1 && i == up1, lim2 && j == up2, lim3 && k == up3, im1 && i== down1, im2 && j == down2, im3 && k == down3);
    29                 }
    30     return dp[len][lim1][lim2][lim3][im1][im2][im3] = ans;
    31 }
    32 
    33 //ll dfs(int len, bool limit1, bool limit2, bool limit3, bool ismin1, bool ismin2, bool ismin3)
    34 //{
    35 //    if (len == -1)
    36 //        return 1;
    37 //        
    38 //    if (dp[len][limit1][limit2][limit3][ismin1][ismin2][ismin3] != -1)
    39 //        return dp[len][limit1][limit2][limit3][ismin1][ismin2][ismin3];
    40 //        
    41 //    int up1 = limit1 ? num2[len] : 1;
    42 //    int up2 = limit2 ? num2[len] : 1;
    43 //    int up3 = limit3 ? num2[len] : 1;
    44 //    int un1 = ismin1 ? num1[len] : 0;
    45 //    int un2 = ismin2 ? num1[len] : 0;
    46 //    int un3 = ismin3 ? num1[len] : 0;
    47 //    ll ans = 0;
    48 //    for (int i = 0; i <= up1; i++)
    49 //    {
    50 //        for (int j = 0; j <= up2; j++)
    51 //        {
    52 //            for (int l = 0; l <= up3; l++)
    53 //            {
    54 //                if (i < un1 || j < un2 || l < un3)
    55 //                    continue;
    56 //                if ((i ^ j ^ l) != (i | j | l))
    57 //                    continue;
    58 //                ans += dfs(len - 1, limit1 && i == up1, limit2 && j == up2, limit3 && l == up3, ismin1 && i == un1, ismin2 && j == un2, ismin3 && l == un3);
    59 //            }
    60 //        }
    61 //    }
    62 //    return dp[len][limit1][limit2][limit3][ismin1][ismin2][ismin3] = ans;
    63 //}
    64 
    65 
    66 ll solve(int l, int r)
    67 {
    68     for (int i = 0; i <= 30; i ++)
    69     {
    70         num1[i] = (l >> i) & 1;
    71         num2[i] = (r >> i) & 1;
    72 //        cout << num1[i] << " " << num2[i] << endl;
    73     }
    74     return dfs(30, true, true, true, true, true, true);
    75 }
    76 
    77 int main()
    78 {
    79     int l, r;
    80     memset(dp, -1, sizeof(dp));
    81     scanf("%d%d", &l, &r);
    82     printf("%lld
    ", solve(l, r));
    83 }
    View Code

    K.Hellow World

    就真Hellow Horld。

  • 相关阅读:
    Centos-7修改yum源为国内的yum源
    让vim显示空格,tab字符,及vim多行注释
    centos查找未挂载磁盘格式化并挂载
    记一次“愉快”的lnmp环境的搭建
    Sublime text3 的安装【解决官网被墙问题】
    php 解决json_encode中文UNICODE转码问题
    linux 下 apache启动、停止、重启命令
    Android利用Fiddler进行网络数据抓包
    ecshop 去版权(前台)
    ecshop 去版权
  • 原文地址:https://www.cnblogs.com/xwdzuishuai/p/12081775.html
Copyright © 2020-2023  润新知