• Educational Codeforces Round 15 (A


    比赛链接:http://codeforces.com/contest/702

    A题求连续最长上升自序列。
    [暴力题] for一遍,前后比较就行了。
     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <vector>
     7 #include <cmath>
     8 #include <ctime>
     9 #include <list>
    10 #include <set>
    11 #include <map>
    12 using namespace std;
    13 typedef long long LL;
    14 typedef pair <int, int> P;
    15 const int N = 1e5 + 5;
    16 int a[N];
    17 
    18 int main()
    19 {
    20     int n;
    21     scanf("%d" , &n);
    22     int temp = 1 , res = 1;
    23     scanf("%d" , a + 1);
    24     for(int i = 2 ; i <= n ; ++i) {
    25         scanf("%d" , a + i);
    26         if(a[i] > a[i - 1]) {
    27             temp++;
    28             res = max(res, temp);
    29         }
    30         else {
    31             temp = 1;
    32         }
    33     }
    34     printf("%d
    " , res);
    35     return 0;
    36 }
    View Code

    B. Powers of Two

    B题求有多少对数的和等于2的幂(即a[i] + a[j] = 2的幂)。

    [map乱搞] 先用map存a[i]出现的次数。因为2的幂的个数也就30多个,那我们可以for一遍a数组,然后枚举2的幂。

    统计mp[2的幂 - a[i]]的大小。要是2的幂-a[i]等于a[i],统计的时候减一就好了。

    最后答案除以2,因为每对重复统计了两次。

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <vector>
     7 #include <cmath>
     8 #include <ctime>
     9 #include <list>
    10 #include <set>
    11 #include <map>
    12 using namespace std;
    13 typedef __int64 LL;
    14 typedef pair <int, int> P;
    15 const int N = 1e5 + 5;
    16 map <LL , LL> mp;
    17 LL num[35];
    18 LL a[N];
    19 
    20 int main()
    21 {
    22     mp.clear();
    23     num[0] = 1;
    24     for(int i = 1 ; i <= 33 ; ++i) {
    25         num[i] = num[i - 1] * 2;
    26     }
    27     int n;
    28     scanf("%d" , &n);
    29     for(int i = 1 ; i <= n ; ++i) {
    30         scanf("%lld" , a + i);
    31         mp[a[i]]++;
    32     }
    33     LL res = 0;
    34     for(int i = 1 ; i <= n ; ++i) {
    35         for(int j = 1 ; j <= 33 ; j++) {
    36             if(num[j] < a[i])
    37                 continue;
    38             res += mp[num[j] - a[i]];
    39             if(num[j] == 2 * a[i])
    40                 res--;
    41         }
    42     }
    43     printf("%lld
    " , res / 2);
    44     return 0;
    45 }
    View Code

    C. Cellular Network

    C题题意是给你n个城市和m个塔的坐标,问你塔的信号半径最少是多少能够覆盖所有的城市。

    [二分答案] 二分半径,每次二分一下 然后判断半径的可行性,可行性的话for一遍就好了。

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <vector>
     7 #include <cmath>
     8 #include <ctime>
     9 #include <list>
    10 #include <set>
    11 #include <map>
    12 using namespace std;
    13 typedef __int64 LL;
    14 typedef pair <int, int> P;
    15 const int N = 1e5 + 5;
    16 LL a[N] , b[N];
    17 int n , m;
    18 
    19 bool check(LL r) {
    20     int index = 1 , cnt = 0;
    21     for(int i = 1 ; i <= n , index <= m; ++i) {
    22         if(a[i] >= b[index] - r && a[i] <= b[index] + r) {
    23             cnt++;
    24             continue;
    25         }
    26         else {
    27             index++;
    28             i--;
    29         }
    30     }
    31     if(cnt >= n)    
    32         return true;
    33     return false;
    34 }
    35 
    36 int main()
    37 {
    38     scanf("%d %d", &n , &m);
    39     for(int i = 1 ; i <= n ; ++i) {
    40         scanf("%lld" , a + i);
    41     }
    42     for(int i = 1 ; i <= m ; ++i) {
    43         scanf("%lld" , b + i);
    44     }
    45     LL l = 0 , r = 2*1e9+1;
    46     while(l < r) {
    47         LL mid = (l + r) / 2;
    48         if(check(mid)) {
    49             r = mid;
    50         }
    51         else {
    52             l = mid + 1;
    53         }
    54     }
    55     printf("%lld
    " , r);
    56     return 0;
    57 }
    View Code

    D. Road to Post Office

    D题条件是:d代表路程长度,k代表车子每行驶k长度就会坏,a代表车行驶单位长度的时间,b代表人走路单位长度的时间,t代表坏的车修好时间。

    车好像一开始没坏,问你最少需要多少时间能到终点。

    [分类讨论] 一开始肯定要开车。后来我是比较车的平均速度(k/(k*a+t))和人的平均速度(1/b)。

    要是人的速度大于等于车的速度,那走路到终点就好了。

    不然的话就开车,但是开车开了k的整数倍,剩下路程(d')要是不到k的话,那讨论剩下的路 人和车谁话的时间最少(min(d'*a+k, d'*b))。

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <vector>
     7 #include <cmath>
     8 #include <ctime>
     9 #include <list>
    10 #include <set>
    11 #include <map>
    12 using namespace std;
    13 typedef __int64 LL;
    14 typedef pair <int, int> P;
    15 const int N = 1e5 + 5;
    16 
    17 int main()
    18 {
    19     LL d , k , a , b , t , res = 0;
    20     cin >> d >> k >> a >> b >> t;
    21     LL ans = d;
    22     d -= k;
    23     res = k*a;
    24     if(d <= 0) { //一开始k < d的情况
    25         cout << a * ans << endl;
    26         return 0;
    27     }
    28     double car = k*1.0 / (a*k + t) , peo = 1.0 / b; //车和人的速度
    29     if(peo >= car) { //人的速度大于等于车的速度
    30         res += d * b;
    31         cout << res << endl;
    32         return 0;
    33     }
    34     LL temp = d;
    35     d -= d / k * k; //车后来开了k的整数倍
    36     res += temp / k * (k*a + t);
    37     if(d > 0) { //剩下的路 车和人 取最小的时间
    38         LL temp1 = t + d * a , temp2 = d * b;
    39         res += min(temp1 , temp2);
    40     }
    41     cout << res << endl;
    42     return 0;
    43 }
    View Code

    E. Analysis of Pathes in Functional Graph

    E题题意是有n个点(编号0 ~ n - 1),n条单向边,i和a[i]相连并指向a[i],然后给你每条边的权值。

    问你从每个点出发,走k条边,走的路径权值和是多少,还有求其中最小的边是多少。

    [倍增法] n条边 所以成环,单向 所以每条路径是唯一的。 可以想象成每个数开头之后的都是循环下去的数组。 

    可以用倍增法 类似RMQ的做法解,先预处理一下,par[i][j]表示从i点开始2^i后的点的编号,sum[i][j]表示i点开始2^j条边的路径权值和,min[i][j]表示i点开始2^j条边中最小的边权。

    查询的时候利用k的二进制性质就行了,也是倍增。

     1 //#pragma comment(linker, "/STACK:102400000, 102400000")
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstdlib>
     5 #include <cstring>
     6 #include <cstdio>
     7 #include <vector>
     8 #include <cmath>
     9 #include <ctime>
    10 #include <list>
    11 #include <set>
    12 #include <map>
    13 using namespace std;
    14 typedef __int64 LL;
    15 typedef pair <int, int> P;
    16 const int N = 1e5 + 5;
    17 int par[N][35];
    18 LL min_val[N][35];
    19 LL sum[N][35];
    20 
    21 void init(int n) {
    22     for(int k = 1; k < 34; ++k) {
    23         for(int i = 0; i < n; ++i) {
    24             par[i][k] = par[par[i][k - 1]][k - 1];
    25             min_val[i][k] = min(min_val[i][k - 1], min_val[par[i][k - 1]][k - 1]);
    26             sum[i][k] = sum[i][k - 1] + sum[par[i][k - 1]][k - 1];
    27         }
    28     }
    29 }
    30 
    31 void solve(int root, LL x) {
    32     LL res_min = 1e8 + 1, res_sum = 0;
    33     for(int k = 0; k < 34; ++k) {
    34         if(x & (1LL << k)) {
    35             res_sum += sum[root][k];
    36             res_min = min(res_min, min_val[root][k]);
    37             root = par[root][k];
    38         }
    39     }
    40     printf("%lld %lld
    ", res_sum, res_min);
    41 }
    42 
    43 int main()
    44 {
    45     int n;
    46     LL m;
    47     scanf("%d %lld", &n, &m);
    48     for(int i = 0; i < n; ++i)
    49         scanf("%d", &par[i][0]);
    50     for(int i = 0; i < n; ++i) {
    51         scanf("%lld", &min_val[i][0]);
    52         sum[i][0] = min_val[i][0];
    53     }
    54     init(n);
    55     for(int i = 0; i < n; ++i) {
    56         solve(i, m);
    57     }
    58     return 0;
    59 }
    View Code

    F题不会

  • 相关阅读:
    XOR Clique
    Live Love
    Wannafly挑战赛24 A:石子游戏
    洛谷 P1060 :开心的金明
    洛谷P1049: 装箱问题
    牛客练习赛26 A:平面
    hihoCoder1151: 骨牌覆盖问题·二
    hihoCoder1143:骨牌覆盖问题·一
    hihoCoder1051 : 补提交卡
    TCP Socket的通讯框架
  • 原文地址:https://www.cnblogs.com/Recoder/p/5723215.html
Copyright © 2020-2023  润新知