• ACdream原创群赛(18)のAK's dream题解


    只做了4题水题ADGI

    A题需要注意的就是“[...]”的输出了,何时输出,何时不输出。

     1 #include <stdio.h>
     2 int main()
     3 {
     4     int n, cur, d;
     5     int cnt = 1;
     6     while(scanf("%d%d%d",&n,&cur,&d)!=EOF)
     7     {
     8         printf("Case #%d: ",cnt++);
     9         if(cur==1)
    10             printf("[<<]");
    11         else
    12             printf("(<<)");
    13         int start = cur - d;
    14         int end = cur + d;
    15         if(start >0 && start!=1 && cur!=1)//说明前面有隐藏页,需要输出[...]
    16             printf("[...]");
    17         for(int i=start; i<=end && i<=n; ++i)
    18         {
    19             if(i <=0 )
    20                 continue;
    21             else
    22             {
    23                 if(i == cur)
    24                     printf("[%d]",i);
    25                 else
    26                     printf("(%d)",i);
    27             }
    28         }
    29         if(end<n && cur!=n)//说明后面有隐藏页,需要输出[...]
    30             printf("[...]");
    31         if(cur==n)
    32             printf("[>>]");
    33         else
    34             printf("(>>)");
    35         printf("
    ");
    36  
    37     }
    38 }
    View Code

    D题应该是数学题吧(分步计数原理),将数组weight 和数组pow排序

    然后分别判断每个数有多少种选择,然后一一相乘取模
    对于第一个hero,如果有a1把剑的weight小于等于power,对于第二个hero,有a2把剑的weight小于等于power,一次类推
    那么第一个英雄有a1种选择,第二个英雄有a2-1种选择,第三个英雄有a3-2种选择,一次类推。
    至于判断有多少把剑的weight小于每个英雄的power,普通查找会超时,要用二分查找。
    二分查找的特性是,对于key,如果数组中有元素与之相等,那么就返回该元素的下标,不然就返回就返回第一个比key大的元素的下标(如果有的话)
    如果没有,就返回数组最后一个元素的下标。 所以我们可以用二分查找找出比power[i]小的weight有多少个

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 using namespace std;
     5 typedef long long LL;
     6 const int N = 100000 + 10;
     7 const int MOD = 1000000007;
     8 int w[N];
     9 int p[N];
    10 void input(int &x)
    11 {
    12     char ch = getchar();
    13     while(ch<'0' || ch >'9')
    14         ch = getchar();
    15     x = 0;
    16     while(ch>='0' && ch<='9')
    17     {
    18         x = x * 10 + ch - '0';
    19         ch = getchar();
    20     }
    21 }
    22 int main()
    23 {
    24     int t;
    25     int n;
    26     int i,j,k,z;
    27     int tCase = 1;
    28     input(t);
    29     while(t--)
    30     {
    31         printf("Case #%d: ",tCase++);
    32         input(n);
    33         for(i=1; i<=n; ++i)
    34             input(w[i]);
    35         for(i=1; i<=n; ++i)
    36             input(p[i]);
    37         sort(w+1, w+n+1);
    38         sort(p+1, p+n+1);
    39         LL ans = 1;
    40         int cnt;
    41         for(i=1; i<=n; ++i)
    42         {
    43             cnt = 0;
    44             int low = 1; int high = n;
    45             int mid;
    46             while(low <= high)
    47             {
    48                  mid = (low + high)/2;
    49                 if(p[i] == w[mid])
    50                     break;
    51                 else if(p[i] >= w[mid])
    52                     low = mid + 1;
    53                 else
    54                     high = mid - 1;
    55             }
    56             if(p[i] < w[mid])
    57                 mid--;
    58             ans = (ans*(mid-i+1))%MOD;
    59         }
    60         printf("%lld
    ",ans);
    61     }
    62 }
    View Code

    G题要没什么,先用字符串读入,判断有没有可能爆,如果有可能,继续进一步的字符串判断,如果没可能,就用sscanf读入,然后判断范围

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string>
     4 using namespace std;
     5 typedef long long LL;
     6 string Max = "9223372036854775807";//19
     7 int main()
     8 {
     9     int i;
    10     string str;
    11     LL num;
    12     while(cin>>str)
    13     {
    14         if(str[0] != '-')  
    15         {
    16             if(str.size() < 19)
    17             {
    18                 sscanf(str.c_str(),"%lld",&num);
    19                 if(num <= 32767)
    20                     puts("short");
    21                 else if(num <= 2147483647)
    22                     puts("int");
    23                 else
    24                     puts("long long");
    25             }
    26             else if(str.size()==19)
    27             {
    28                 if(str > Max)
    29                     puts("It is too big!");
    30                 else
    31                     puts("long long");
    32             }
    33             else
    34                 puts("It is too big!");
    35         }
    36         else
    37         {
    38             if(str.size() < 20)
    39             {
    40                 sscanf(str.c_str(),"lld",&num);
    41                 if(num >= -32767)
    42                     puts("short");
    43                 else if(num >= 2147483647)
    44                     puts("int");
    45                 else
    46                     puts("long long");
    47  
    48             }
    49             else if(str.size() == 20)
    50             {
    51                 str.erase(str.begin());
    52                 if(str > Max)
    53                     puts("It is too big!");
    54                 else
    55                     puts("long long");
    56             }
    57             else
    58                 puts("It is too big!");
    59  
    60         }
    61     }
    62 }
    View Code

    I题要注意的就是最大公约数可能是负数的情况,导致负号出现在分母。应该处理一下再输出。

     1 #include <stdio.h>
     2 const int N = 1000 + 10;
     3 int gcd(int n, int m)
     4 {
     5     if(m == 0)
     6         return n;
     7     return gcd(m,n%m);
     8 }
     9 int main()
    10 {
    11     int n, i;
    12     int coe,exp;
    13     while(scanf("%d",&n)!=EOF)
    14     {
    15         for(i=1; i<n; ++i)
    16         {
    17             scanf("%d%d",&coe,&exp);
    18             if( coe % (exp+1)==0)
    19                 printf("%d %d ",coe / (exp+1),exp+1);
    20             else
    21             {
    22                 int g = gcd(coe, exp+1);
    23                 if(g>0)
    24                     printf("%d/%d %d ",coe/g,(exp+1)/g, exp+1);
    25                 else
    26                     printf("%d/%d %d ",-coe/g,-(exp+1)/g, exp+1);
    27      
    28             }  
    29         }
    30         scanf("%d%d",&coe,&exp);
    31         if( coe % (exp+1)==0)
    32             printf("%d %d
    ",coe / (exp+1),exp+1);
    33         else
    34         {
    35             int g = gcd(coe, exp+1);
    36             if(g>0)
    37                 printf("%d/%d %d
    ",coe/g,(exp+1)/g, exp+1);
    38             else
    39                 printf("%d/%d %d
    ",-coe/g,-(exp+1)/g, exp+1);
    40         }  
    41     }
    42 }
    View Code

    J题如果正向模拟,i要不断回溯,导致复杂度时间复杂是O(n*m).但是如果是逆向模拟,i不用回溯,时间复杂度是O(n+m).

     1 #define _CRT_SECURE_NO_DEPRECATE
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <algorithm>
     5 using namespace std;
     6 const int N = 1000000 + 10;
     7 struct node
     8 {
     9     int val;
    10     int index;
    11     bool operator<(const node &rhs)const
    12     {
    13         return val > rhs.val;
    14     }
    15 }a[N];
    16 int hash[N];
    17 int ans[N];
    18 int op[N];
    19 int main()
    20 {
    21     int t,n,m,tCase = 1,i,j;
    22     scanf("%d",&t);
    23     while(t--)
    24     {
    25         memset(hash,0,sizeof(hash));
    26         scanf("%d%d",&n,&m);
    27         for(i=0; i<n; ++i)
    28         {
    29             scanf("%d",&a[i].val);
    30             a[i].index = i;
    31         }
    32         sort(a,a+n);
    33         for(i=0; i<m; ++i)
    34             scanf("%d",&op[i]);
    35         int cnt = 0;
    36         printf("Case #%d: ",tCase++);
    37         for(i=0,j=m-1;j>=0;--j)
    38         {
    39             for(; i<n; ++i)
    40             {
    41                 if(a[i].val <= op[j])
    42                     break;
    43                 int index = a[i].index;
    44                 hash[index] = true;
    45                 if(!hash[index-1] && !hash[index+1])//如果下标的左右都没有被标记过,则该下标自成一块
    46                     cnt++;
    47                 else if(hash[index-1] && hash[index+1])//因为该下标的加入,导致该下标的左右连在一起,2变1
    48                     cnt--;
    49             }
    50             ans[j] = cnt;
    51         }
    52         for(i=0; i<m-1; ++i)
    53             printf("%d ",ans[i]);
    54         printf("%d
    ",ans[m-1]);
    55 
    56     }
    57 }
    View Code
  • 相关阅读:
    计算机组成原理
    数据结构和算法: 字符串匹配(一) BF/RK
    数据结构和算法: 动态规划-台阶问题
    数据结构和算法: 散列表
    数据结构和算法: 归并排序/快速排序
    数据结构与算法: 冒泡/插入/选择排序
    过渡内容
    Redis 和缓存技术
    2019字节跳动面试时手撕代码题
    Mysql锁机制
  • 原文地址:https://www.cnblogs.com/justPassBy/p/3960138.html
Copyright © 2020-2023  润新知