Algorithm小思路小技巧

数学题

  • 小明用字母A 对应数字1,B 对应2,以此类推,用Z 对应26。对于27以上的数字,小明用两位或更长位的字符串来对应,例如AA 对应27,AB 对应28,AZ 对应52,LQ 对应329。请问2019 对应的字符串是什么?

    • 用ABCD替换掉了1234, 注意26个字母应该是逢27进1, 也就是27进制, 而不是26进制
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      %法一
      #include <cstdio>
      #include <iostream>
      using namespace std;
      string solve(int n, int r){
      string ret;
      while(n > 0){
      int t = n%r;
      n = (n-1)/r; //不是26进制
      if(t == 0) t = 26;
      ret += 'A'+t-1;
      }
      return ret;
      }
      int main()
      {
      int n;
      cin >> n;
      string ans = solve(n, 26);
      for(int i = ans.length()-1; i >= 0; i--)
      cout << ans[i];

      return 0;
      }


      %法二
      #include <bits/stdc++.h>
      using namespace std;
      //702 --> ZZ
      //703 --> AAA
      //18278 --> ZZZ
      //18279 --> AAAA
      void dfs(int N) {
      if (N > 26) dfs((N - 1) / 26);
      putchar('A' + (N - 1) % 26);
      }
      int main() {
      int N;
      while (cin >> N) {
      dfs(N); cout << endl;
      }
      return 0;
      }
    • n转r进制的模板
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      	void solve(int n, int r)
      {
      char ans[maxn], index = 0;
      ms(ans, 0);
      while(n > 0){
      int t = n%r;
      n /= r;
      if(t > 9)
      ans[index++] = (t-10+'A');
      else
      ans[index++] = (t+'0');
      }
      }
      //从后往前输出
  • 给定数列1, 1, 1, 3, 5, 9, 17, …,从第4 项开始,每项都是前3 项的和。求第20190324 项的最后4 位数字。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    %一
    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 30000000;
    int a[MAXN];
    int main() {
    int N = 20190324;
    a[1] = a[2] = a[3] = 1;
    for (int i = 4; i <= N; ++i)
    a[i] = (a[i - 1] + a[i - 2] + a[i - 3]) % 10000;
    printf("%d\n", a[N]);
    return 0;
    }

    %二
    #include <cstdio>
    using namespace std;
    int main() {
    int a = 1, b = 1, c = 1;
    int N = 20190324; //scanf("%d", &N);
    for (int i = 4; i <= N; ++i) {
    int t = (a + b + c) % 10000;
    c = b;
    b = a;
    a = t;
    }
    printf("%d\n", a);
    return 0;
    }
  • 把2019 分解成3 个各不相同的正整数之和,并且要求每个正整数都不包含数字 2 和 4,一共有多少种不同的分解方法?注意交换3个整数的顺序被视为同一种方法,例如1000+1001+18 和 1001+1000+18 被视为同一种。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #include <bits/stdc++.h>
    using namespace std;
    bool isOK(int x) {
    for (/* */; x > 0; x /= 10)
    if (x % 10 == 2 || x % 10 == 4) return false;
    return true;
    }
    int main() {
    int N = 2019;
    int cnt = 0;
    for (int i = 1; i < N / 3; ++i)
    if (isOK(i))
    //k = N - i - j > j
    //判断重复可以i < j < k, 然后判断i, j, k是否含2和4就行了
    for (int j = i + 1; N - i - j > j; ++j)
    if (isOK(j) && isOK(N - i - j)) ++cnt;
    cout << cnt << endl;
    return 0;
    }
  • 小明对数位中含有 2、0、1、9 的数字很感兴趣(不包括前导0),在1 到 40 中这样的数包括1、2、9、10 至 32、39 和 40,共 28 个,他们的和是 574。请问,在 1 到n 中,所有这样的数的和是多少?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #include <bits/stdc++.h>
    using namespace std;
    int N;
    bool isOK(int x) {
    for (/* */; x > 0; x /= 10) {
    int t = x % 10;
    if (t % 10 == 2 || t % 10 == 0 || t % 10 == 1 || t % 10 == 9)
    return true;
    }
    return false;
    }
    int main() {
    cin >> N;
    int ret = 0;
    for (int i = 1; i <= N; ++i)
    if (isOK(i)) ret += i;
    cout << ret << endl;
    return 0;
    }
  • 奕奕的几何很差,然而奕奕并不承认,所以华华扔给奕奕一道题目。如图: 已知大半圆的半径等于两个小半圆半径之和。若给出红色部分的面积,那么大圆的半径最小是多少呢?反正奕奕是不会的,所以现在请你回答。

    • 链接:https://ac.nowcoder.com/acm/contest/894/A
      来源:牛客网
    • 精度问题,因为刚开始使用pi = 3.1415,通过很少样例,然后改用3.14159265,通过的多一些,之后改用acos(-1)通过更多,然后因为s刚开始为int型,所以后改用为double类型,才通过所有样例
    • 注意.3lf输出时,用四舍五入,该题精度有四舍五入
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      #include<cstdio>
      #define pi 3.14259265
      #include<cmath>
      int main(){
      double s;
      double r;
      scanf("%lf", &s);
      r =sqrt( 4*s/acos(-1));
      printf("%.3lf", r);
      }

枚举a的每一位

1
2
3
4
while(a != 0){
if(a%10 == m) ...
a /= 10;
}
------ The Happy Ending ------