AtCoder Beginner Contest 042 题解


目录
  • A - Iroha and Haiku (ABC Edition)
    • 题目大意:
  • B - Iroha Loves Strings (ABC Edition)
    • 题目大意:
    • 分析:
  • C - Iroha's Obsession
    • 题目大意:
    • 分析:
  • D - Iroha and a Grid
    • 题目大意

A - Iroha and Haiku (ABC Edition)

题目大意:

判断输入的三个数字是不是 5,5,7。

#include
#define ll long long
#define INF 0x7f7f7f7f //2139062143
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define Equ(a,b) (fabs((a)-(b))(eps))
#define x first
#define y second
using namespace std;
const int N=1e6+7;
const double eps=1e-6;
const int mod=1e9+7;
int a[N];
int main (){
    IOS
    int x, y, z; cin >> x >> y >> z;
    a[x] ++; a[y] ++; a[z] ++;
    if (a[5] == 2 && a[7] == 1){
        cout << "YES" << endl;
    }
    else cout << "NO" << endl;
    
    return 0;
}

B - Iroha Loves Strings (ABC Edition)

题目大意:

给出若干个字符串,如何首位拼接得到字典序最小的字符串。

分析:

利用 c++ string 类型的比较就是按字典序比较,然后排序输出即可

#include
#define ll long long
#define INF 0x7f7f7f7f //2139062143
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define Equ(a,b) (fabs((a)-(b))(eps))
#define x first
#define y second
using namespace std;
const int N=1e6+7;
const double eps=1e-6;
const int mod=1e9+7;
string s[N];
int main (){
    IOS
    int n, l; cin >> n >> l;
    for (int i = 1 ; i <= n ; i ++) cin >> s[i];
    sort (s + 1, s + n + 1);
    for (int i = 1 ; i <= n ; i ++) cout << s[i];
    return 0;
}

C - Iroha's Obsession

题目大意:

给出数字的使用限制,用剩下的数字拼成大于等于 \(n\) 的数并输出。

分析:

题给出的 \(n\) 较小,直接从 \(n\) 开始枚举,并 check 构成数字的合法性即可。复杂度 \(O(n)\)

赛中,脑抽尝试去构造。构造细节较多,并不好写,但是复杂度可以达到 \(O(\lg_ n)\)

#include
#define ll long long
#define INF 0x7f7f7f7f //2139062143
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define Equ(a,b) (fabs((a)-(b))(eps))
#define x first
#define y second
using namespace std;
const int N=1e6+7;
const double eps=1e-6;
const int mod=1e9+7;
int a[N];
bool check (int n){
    while (n){
        if (a[n % 10]) return 0;
        n /= 10;
    }
    return 1;
}
int main (){
    IOS
    int n, k; cin >> n >> k;
    for (int i = 1, x ; i <= k ; i ++){
        cin >> x;
        a[x] = 1;
    }
    while (!check (n)){
        n ++;
    }
    cout << n << endl;
    return 0;
}

脑子不清楚时候写的构造(可ac)

#include
#define ll long long
#define INF 0x7f7f7f7f //2139062143
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define Equ(a,b) (fabs((a)-(b))(eps))
#define x first
#define y second
using namespace std;
const int N=1e6+7;
const double eps=1e-6;
const int mod=1e9+7;
int a[N];
int main (){
    IOS
    string k;int n; cin >> k >> n;
    for (int i = 1, x ; i <= n ; i ++) {
        cin >> x; a[x] = 1;
    }
    char minn, minn2;
    for (int i = 0 ; i <= 9 ; i ++){
        if (!a[i]){
            minn = i + '0';
            break;
        }
    }
    for (int i = 1 ; i <= 9 ; i ++){
        if (!a[i]){
            minn2 = i + '0';
            break;
        }
    }
    string ans;
    bool flag = 1;
    for (int i = k.size () - 1; i >= 0 ; i --){
        bool f = 0;
        bool f1 = 0;
        for (int j = 0 ; j <= 9 ; j ++){
            if (a[j]) continue;
            if (j >= k[i] - '0'){
                if (!flag && j == k[i] - '0') continue; 
                f1 = j != k[i] - '0';
                ans = (char)(j + '0') + ans;
                f = 1;
                break;
            }
        }        
        flag = f;
        if (f1){
            if (ans.size () > 1){
                for (int i = ans.size () - 1; i >= 1 ; i --) ans[i] = minn;
            }
        }
        if (!f) {
            ans += minn;
            for (int i = 0 ; i < ans.size () ; i ++) ans[i] = minn;
        }
    }
    if (!flag)
        cout  << minn2 + ans << endl;
    else {
        cout << ans << endl;
    }
    return 0;
}

D - Iroha and a Grid

题目大意

很经典的问题,从一个表格的左上角走到右下角有几种走法 (只能向下或者向右)。加上一定左下角一块区域不能走的限制。通常会采用 \(dp\), 或者是组合数的方法解决。数据范围 \(1e5\) ,因此不能用 \(dp\) 。因而尝试用组合数分段处理,难度不大。

详情见代码注释部分

#include
#define ll long long
#define INF 0x7f7f7f7f //2139062143
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define Equ(a,b) (fabs((a)-(b))(eps))
#define x first
#define y second
using namespace std;
const int N=1e6+7;
const double eps=1e-6;
const int mod=1e9+7;
int a[N], f[N], invf[N];
ll qpow(ll base, ll power) {
    ll result = 1;
    while (power > 0) {
        if (power & 1) {
            result = result * base % mod;
        }
        power >>= 1;
        base = (base * base) % mod;
    }
    return result;
}
void init(){
    f[0] = 1;
    for(int i = 1 ; i < N ; i ++) f[i] = 1ll * f[i - 1] * i % mod;
    invf[N - 1] = qpow(f[N - 1], mod - 2);
    for(int i = N - 2; i >= 0 ; i --) invf[i] = 1ll * invf[i + 1] * (i + 1) % mod;
}
ll c(ll a,ll b){
    if (a < b) return 0;
    return 1ll * f[a] * invf[a - b] % mod * invf[b] % mod;
}
int main (){
    ll h, w, a, b; cin >> h >> w >> a >> b; 
    init();
    // 对区间[b + 1, w] 的 i 先算 (1, 1) 到 (h - a, i)的方案数, 再算 (h - a + 1, i) 到 (h, w)的方案数, 两者相乘即可
    ll ans = 0;
    for (int i = b + 1 ; i <= w ; i ++){
        ll ans1 = c((h - a - 1) + i - 1, i - 1), ans2 = c(a - 1 + w - i, a - 1);
        ans = ans + ans1 * ans2 % mod;
        ans %= mod;
    } 
    cout << ans << endl;
    return 0;
}