AtCoder Beginner Contest 178 A

题目链接

A - Not

思路:

代码:
/*
 * @Author       : nonameless
 * @Date         : 2020-09-13 19:55:56
 * @LastEditors  : nonameless
 * @LastEditTime : 2020-09-13 20:00:55
 */
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define sz(x) (int)x.size()
#define toStr(name) (#name)
#define all(x) x.begin(), x.end()
using namespace std;
typedef long long ll;
typedef pair<ll, ll> PLL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const double eps = 1e-6;
const double PI  = acos(-1.0);
const int INF = 0x3f3f3f3f;
const ll LNF  = 0x3f3f3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b,a % b):a;}
inline ll  gcd(ll  a, ll  b) { return b ? gcd(b,a % b):a;}
inline int lcm(int a, int b) { return a * b / gcd(a, b); }

template<class T>
inline void read(T &x){
    x = 0;
    int f = 1;
    char c = getchar();
    while(c < '0' || c > '9') if(c == '-') { f = -1; c = getchar(); }
    while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    x = x * f;
}

template<class T>
inline void out(string a, T x){ cout << a << " = " << x << endl; }


int main(){

    int x; read(x);
    if(x == 0) puts("1");
    if(x == 1) puts("0");

    
    return 0;
}

B - Product Max

思路:

显然答案只会出现在端点的相乘上,所以暴力枚举出四种情况取 (max) 即可。

代码:
/*
 * @Author       : nonameless
 * @Date         : 2020-09-13 20:02:06
 * @LastEditors  : nonameless
 * @LastEditTime : 2020-09-14 00:51:31
 */
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define sz(x) (int)x.size()
#define toStr(name) (#name)
#define all(x) x.begin(), x.end()
using namespace std;
typedef long long ll;
typedef pair<ll, ll> PLL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const double eps = 1e-6;
const double PI  = acos(-1.0);
const int INF = 0x3f3f3f3f;
const ll LNF  = 0x3f3f3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b,a % b):a;}
inline ll  gcd(ll  a, ll  b) { return b ? gcd(b,a % b):a;}
inline int lcm(int a, int b) { return a * b / gcd(a, b); }

template<class T>
inline void read(T &x){
    x = 0;
    int f = 1;
    char c = getchar();
    while(c < '0' || c > '9') if(c == '-') { f = -1; c = getchar(); }
    while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    x = x * f;
}

template<class T>
inline void out(string a, T x){ cout << a << " = " << x << endl; }


int main(){

    ll a, b, c, d; cin >> a >> b >> c >> d;
    ll ans = -LNF;
    ans = max(ans, a * c);
    ans = max(ans, a * d);
    ans = max(ans, b * c);
    ans = max(ans, b * d);
    cout << ans << endl;
    return 0;
}

C - Ubiquity

思路:

直接考虑不方便,所以我们考虑不合法的方案数。

先用快速幂算出 (10^n) 即总方案数。

然后枚举不合法的情况:

  • 只有 (0) 的情况:(sum_{i=1}^nC_n^i imes 8^{n-i})。((i)(0) 出现的个数)
  • 只有 (9) 的情况:与 (0) 的一样
  • 没有 (0, 9) 的情况:(8^n)

然后减去上述情况即可。

代码:
/*
 * @Author       : nonameless
 * @Date         : 2020-09-13 20:14:14
 * @LastEditors  : nonameless
 * @LastEditTime : 2020-09-13 20:38:55
 */
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define sz(x) (int)x.size()
#define toStr(name) (#name)
#define all(x) x.begin(), x.end()
using namespace std;
typedef long long ll;
typedef pair<ll, ll> PLL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const double eps = 1e-6;
const double PI  = acos(-1.0);
const int INF = 0x3f3f3f3f;
const ll LNF  = 0x3f3f3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b,a % b):a;}
inline ll  gcd(ll  a, ll  b) { return b ? gcd(b,a % b):a;}
inline int lcm(int a, int b) { return a * b / gcd(a, b); }

template<class T>
inline void read(T &x){
    x = 0;
    int f = 1;
    char c = getchar();
    while(c < '0' || c > '9') if(c == '-') { f = -1; c = getchar(); }
    while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    x = x * f;
}

template<class T>
inline void out(string a, T x){ cout << a << " = " << x << endl; }

const int mod = 1e9 + 7;

const int N = 1e6 + 10;

ll f[N];

ll qpow(ll a, ll b){
    ll res = 1;
    while(b){
        if(b & 1) res = res * a % mod;
        b >>= 1;
        a = a * a % mod;
    }
    return res;
}

ll C(ll a, ll b){
    return f[a] * (qpow(f[b] * f[a - b] % mod, mod - 2)) % mod;
}



int main(){

    f[0] = 1;
    for(int i = 1; i < N; i ++) f[i] = f[i - 1] * i % mod;

    ll n; read(n);
    if(n == 1) puts("0");
    else{
        ll ans = qpow(10, n);
        ll t1 = 0;
        for(int i = 1; i <= n; i ++){
            t1 = (t1 + C(n, i) * qpow(8, n - i) * 2 % mod) % mod;
        }
        t1 = (t1 + qpow(8, n)) % mod;
        ans = (ans - t1 + mod) % mod;
        cout << ans << endl;
    }
    return 0;
}

D - Redistribution

思路:

(f[i][j]) :长度为 (i) 且和为 (j) 的序列的个数。

那么转移方程有:(f[i][j] = f[i][j] + f[i-1][j-k](3leq kleq j))

但是这样枚举是有三重循环,显然超时,所以考虑优化掉一重循环。

观察方程可以发现 (f[i-1][j-k]) 是可以用前缀和求出来的,因为他就是上一层计算出来的,所以我们可以在处理完 (i) 的时候,求出当前长度的前缀和供下一层使用。

注意边界的初始化。对长度为 (0) 的也要求一次前缀和。

代码:
/*
 * @Author       : nonameless
 * @Date         : 2020-09-13 20:40:53
 * @LastEditors  : nonameless
 * @LastEditTime : 2020-09-14 00:59:44
 */
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define sz(x) (int)x.size()
#define toStr(name) (#name)
#define all(x) x.begin(), x.end()
using namespace std;
typedef long long ll;
typedef pair<ll, ll> PLL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const double eps = 1e-6;
const double PI  = acos(-1.0);
const int INF = 0x3f3f3f3f;
const ll LNF  = 0x3f3f3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b,a % b):a;}
inline ll  gcd(ll  a, ll  b) { return b ? gcd(b,a % b):a;}
inline int lcm(int a, int b) { return a * b / gcd(a, b); }

template<class T>
inline void read(T &x){
    x = 0;
    int f = 1;
    char c = getchar();
    while(c < '0' || c > '9') if(c == '-') { f = -1; c = getchar(); }
    while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    x = x * f;
}

template<class T>
inline void out(string a, T x){ cout << a << " = " << x << endl; }

const int N = 2e3 + 10;

const int mod = 1e9 + 7;

int f[N / 3][N];

int main(){

    int s; read(s);
    ll ans = 0;
    f[0][0] = 1;
    for(int i = 1; i <= s; i ++) f[0][i] = 1;
    for(int i = 1; i <= s / 3; i ++){
        for(int j = 3; j <= s; j ++){
            f[i][j] = (f[i][j] + f[i - 1][j - 3]) % mod;
            ans = (ans + f[i][s]) % mod;
        }
        for(int j = 1; j <= s; j ++) f[i][j] = (f[i][j] + f[i][j - 1]) % mod;
    }

    cout << ans << endl;
    
    return 0;
}

E - Dist Max

思路:

这其实就是一个最远曼哈顿距离的模板题(奈何我不知道)。

参考博客

由:(|a - b| = max(a - b, b - a))

那么可以将 (|x_i-x_j|+|y_i-y_j|) 变为在下面四种情况中取 (max)

  • ((x_i-x_j) + (y_i-y_j))
  • ((x_i-x_j)+(y_j-y_i))
  • ((x_j-x_i)+(y_i-y_j))
  • ((x_j-x_i)+(y_j-y_i))

我们利用交换律将一个点的坐标放在一起:

  1. ((x_i+y_i)+(-x_j-y_j))
  2. ((x_i-y_i)+(-y_i+y_j))
  3. ((-x_i+y_i)+(x_j-y_j))
  4. ((-x_i-y_i)+(x_j+y_j))

我们可以发现其实就只有两种情况了((1,4) 是一种情况,(2, 3) 是一种情况)即:

  • ((x_i+y_i)+(-x_j-y_j))
  • ((x_i-y_i)+(-y_i+y_j))
代码:
/*
 * @Author       : nonameless
 * @Date         : 2020-09-14 00:38:45
 * @LastEditors  : nonameless
 * @LastEditTime : 2020-09-14 00:45:05
 */
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define sz(x) (int)x.size()
#define toStr(name) (#name)
#define all(x) x.begin(), x.end()
using namespace std;
typedef long long ll;
typedef pair<ll, ll> PLL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const double eps = 1e-6;
const double PI  = acos(-1.0);
const int INF = 0x3f3f3f3f;
const ll LNF  = 0x3f3f3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b,a % b):a;}
inline ll  gcd(ll  a, ll  b) { return b ? gcd(b,a % b):a;}
inline int lcm(int a, int b) { return a * b / gcd(a, b); }

template<class T>
inline void read(T &x){
    x = 0;
    int f = 1;
    char c = getchar();
    while(c < '0' || c > '9') if(c == '-') { f = -1; c = getchar(); }
    while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    x = x * f;
}

template<class T>
inline void out(string a, T x){ cout << a << " = " << x << endl; }

vector<int> v1, v2, v3, v4;

bool cmp(int a, int b) { return a > b; }


int main(){

    int n; read(n);
    for(int i = 1; i <= n; i ++){
        int x, y; 
        read(x); read(y);
        v1.pb(x + y);
        v2.pb(-x - y);
        v3.pb(-x + y);
        v4.pb(x - y);
    }
    sort(all(v1), cmp); sort(all(v2), cmp); sort(all(v3), cmp); sort(all(v4), cmp);
    int ans = max(v1[0] + v2[0], v3[0] + v4[0]);
    cout << ans << endl;
    return 0;
}

原文地址:https://www.cnblogs.com/nonameless/p/13664377.html