AcWing第88场周赛题解

AcWing第88场周赛题解

T1

https://www.acwing.com/problem/content/4803/
给定一个整数 x,请你找到严格大于 x 且各位数字均不相同的最小整数 y。数据范围1000 ≤ \le x ≤ \le 9000

思路

从x+1枚举答案即可。

参考代码(C++)

#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>

using namespace std;

bool check(int x) {
    set<int> S;
    while(x) {
        if(S.count(x % 10)) return false;
        S.insert(x % 10);
        x /= 10;
    }
    return true;
}

int main() {
    int x;
    cin >> x;
    for(int i = x + 1; ; i ++) {
        if(check(i)) {
            cout << i << endl;
            return 0;
        }
    }
    
    return 0;
}

T2

https://www.acwing.com/problem/content/4804/
给定一个平面。平面中有 n条与 x轴平行的有向边,从上到下依次编号为 1∼n,每条边都无限长,且两两不重合。平面中有 m条与 y轴平行的有向边,从左到右依次编号为 1∼m,每条边都无限长,且两两不重合。这些边一共有 n×m 个交点。给定每条边的具体方向,请你判断这 n×m个交点是否满足:从任意交点出发可以到达任意其它交点。

算法

n条x方向的直线与m条y方向的直线所形成的点共有n × \times ×m个,枚举每个点,每个点之间可达情况可以根据直线的方向来确定,在这个过程中建图,最后对每一个点跑一遍爆搜。

参考代码(C++)

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

const int N = 410;

int n, m;
string a, b;

vector<int> g[N];
bool st[N];

void dfs(int u, int f) {
    st[u] = true;
    for(auto& ne : g[u]) {
        if(ne == f) continue;
        if(!st[ne]) dfs(ne, u);
    }
}

int main() {
    cin >> n >> m;
    cin >> a >> b;
    
    for(int i = 0; i < n; i ++)
        for(int j = 0; j + 1 < m; j ++) {
            if(a[i] == '>') g[i * m + j].push_back(i * m + j + 1);
            else g[i * m + j + 1].push_back(i * m + j);
        }
        
    for(int j = 0; j < m; j ++) {
        for(int i = 0; i + 1 < n; i ++) {
            if(b[j] == 'v') g[i * m + j].push_back((i + 1) * m + j);
            else g[(i + 1) * m + j].push_back(i * m + j);
        }
    }
    
    
    memset(st, 0, sizeof st);
    
    dfs(0, -1);
    
    bool flag = true;
    for(int i = 0; i < n * m; i ++) {
        dfs(i, -1);
        for(int i = 0; i < n * m; i ++) {
            if(!st[i]) flag = false;
        }
        if(!flag) break;
        memset(st, 0, sizeof st);
    }
    
    if(flag) cout << "YES" << endl;
    else cout << "NO" << endl;
    return 0;
}

T3

https://www.acwing.com/problem/content/4805/
金明有 n天假期,编号 1∼n1。

整个假期期间,他每天只可能有三种选择:

  1. 去健身房健身一整天。(前提是当天健身房开放)
  2. 去图书馆看书一整天。(前提是当天图书馆开放)
  3. 在家休息一整天。

用一个长度为 n的整数数组 a1,a2,…,an,…, 来表示这 n天健身房与图书馆的开放情况,其中:

  • ai 等于 0表示第 i天健身房关闭且图书馆关闭。
  • ai等于 1 表示第 i天健身房关闭但图书馆开放。
  • ai等于 2 表示第 i天健身房开放但图书馆关闭。
  • ai等于 3 表示第 i健身房开放且图书馆开放。

金明希望自己用来休息的天数尽可能少,但是,他一定不会**连续两天(或更多天)去健身房健身,也一定不会连续两天(或更多天)**去图书馆看书。

请你计算,金明用来休息的最少可能天数。

算法

枚举每一天,当前枚举一天中,小明只能有三个选择,1.选择在家里休息,不会有任何之前的限制;2.选择去健身馆,那么当天的健身馆应是开启状态,并且其一天不能选择去健身馆;3.选择去图书馆,那么当天的图书馆应是开启状态,并且前一天不能选择去图书馆。

参考代码(C++)

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 110;

int n;
int a[N];
int f[N][3];

int main() {
    cin >> n;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    
    memset(f, 0x3f, sizeof f);
    f[0][0] = f[0][1] = f[0][2] = 0;
    
    for(int i = 1; i <= n; i ++) {
        f[i][0] = min({f[i - 1][0], f[i - 1][1], f[i - 1][2]}) + 1;
        if(a[i] == 1 || a[i] == 3) f[i][1] = min({f[i - 1][0], f[i - 1][2]});
        if(a[i] == 2 || a[i] == 3) f[i][2] = min({f[i - 1][0], f[i - 1][1]});
    }
    
    cout << min({f[n][0], f[n][1], f[n][2]}) << endl;
    return 0;
}
posted @ 2023-01-28 20:24  openallzzz  阅读(5)  评论(0编辑  收藏  举报  来源