六月11号补题日记:acwing 周赛107

竞赛 - AcWing

A

题意很简单:

但是这个题目的代码自己写复杂了

根本用不到那么多的分类:能用一种情况说明的,不要把情况弄复杂:

B

二元组:显然是不能用暴力枚举,时间复杂度太高了

这个当时自己写的时候 也考虑过如果当n== 多少的时候,m==1

当时自己是这样枚举的: x = 0 的时候 y = 0 5 10 15

                                         x = 1的时候 y = 4 9 14 19 

                                         x = 2的时候 y = 3 7 12 18

的确,如果说这个样子枚举的,一点都不形象,根本没有办法来写代码,我自己能够主动动手进行枚举这个夸一下,但是枚举的技巧不够,

如果我们是这样枚举的化是不是代码容易一点呢:

                                         当x % 5 = 0 的时候,y % 5 = 0

这句话包含了:x = 0 以及x 为5 y = 0 y 是5的倍数的时候的所有情况

                                         当x % 5 = 1的时候,y % 5  = 4 

这句话包含了 像是1,4;1,9;这样的所有的情况,所以说这个取模是非常的牛逼的

所以上述枚举的所有的情况是这样的:

(0,0)

(1,4)

(2,3)

(3,2)

(4,1)

接下来就是统计在1~n中所有取模为r的数的个数:

int s[5] = {0,1,2,3,4};
for(int i = 1;i <= n;i ++){
    s[i % 5] ++;
}
//或者有一个感觉更加美丽的做法:
//我门通过分析可以知道
//r = 0的时候,n / 5
//r > 0的时候 n % 5 > r n / 5 + 1
//n % 5 < r n / 5
 
#include 
using namespace std;
#define endl '\n'
int get(int n,int r){
    
    if(!r) return n / 5;
    if(n % 5 >= r) return n / 5 + 1;
    return n / 5;
    
}
int main(){
    int n,m;
    cin >> n >> m;
    
    long long res = (long long )get(n,0)*get(m,0);
    for(int i = 1;i <= 4;i ++){
        res += (long long )get(n,i) * get(m,5 - i);
    }
    cout << res << endl;
    return 0;
}
//注意这里 必须要有强制类型转换 赋值计算表达式是先计算右边,然后计算左边
//所以右边可能会爆,所以要加上强制类型转换,当然也可以在写函数的时候类型设置成long long的

C

区间异或:对于区间的几个算法:y总说的,我没有一个是非常熟练的:

这里需要用线段树:没有任何的必要完全去会书写这个数据结构,但是对于这个代码的运用的熟练程度必须有:

你可能感兴趣的:(算法)