9.9 头条笔试编程题

A
题意:找出一段最长的区间, 是的这个区间内的字符串各不相同
思路:滑动窗口

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
// #include 
#include 

using namespace std;

#define LL long long
#define pb push_back
#define mk make_pair
#define pill pair
#define fi first
#define se second
#define mst(a, b) memset(a, b, sizeof a)
#define lson (rt << 1)
#define rson ((rt << 1) | 1)

const int qq = 1e5 + 10;
const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
char st[qq];
int ct[qq];

int main() {
    #ifdef ONLINE_JUDGE
    #else
        freopen("in.txt", "r", stdin);
    #endif
    scanf("%s", st);
    int n = strlen(st);
    int maxn = 0, l = 0;
    for (int i = 0; i < n; ++i) {
        if (ct[st[i]] == 0) {
            ct[st[i]]++;
        } else {
            while (ct[st[l]]--) {
                l++;
                if (ct[st[i]] == 0) break;
            }
            ct[st[i]]++;
        }
        maxn = max(maxn, i - l + 1);
    }
    printf("%d\n", maxn);
    return 0;
}

B

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
// #include 
#include 

using namespace std;

#define LL long long
#define pb push_back
#define mk make_pair
#define pill pair
#define fi first
#define se second
#define mst(a, b) memset(a, b, sizeof a)
#define lson (rt << 1)
#define rson ((rt << 1) | 1)

const int qq = 1e3 + 10;
const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
int num[qq][qq];
int n;
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};

void dfs(int x, int y) {
    num[x][y] = 0;
    for (int i = 0; i < 4; ++i) {
        int a = x + dx[i];
        int b = y + dy[i];
        if (a < 0 || b < 0 || a >= n || b >= n) continue;
        if (num[a][b] == 0) continue;
        dfs(a, b);
    }
}

int main() {
    #ifdef ONLINE_JUDGE
    #else
        freopen("in.txt", "r", stdin);
    #endif
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            scanf("%d", &num[i][j]);
        }
    }
    int Bcnt = 0;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            if (num[i][j] == 1) {
                dfs(i, j);
                Bcnt++;
            }
        }
    }
    printf("%d\n", Bcnt);
    return 0;
}

C
题意: 求有多少种形成一个ip地址
思路: 实际是说在n - 1个空中选择三个点, 最终要能形成一个ip地址, 注意ip地址不带前缀0, 直接二进制枚举

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
// #include 
#include 

using namespace std;

#define LL long long
#define pb push_back
#define mk make_pair
#define pill pair
#define fi first
#define se second
#define mst(a, b) memset(a, b, sizeof a)
#define lson (rt << 1)
#define rson ((rt << 1) | 1)

const int qq = 1e5 + 10;
const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
char st[qq];

int getOne(int x) {
    int cnt = 0;
    while (x > 0) {
        cnt++;
        x = x & (x - 1);
    }
    return cnt;
}

bool check(int x, int y) {
    int cnt = 0;
    if (x == 0) cnt = 1;
    while (x > 0) {
        cnt++;
        x /= 10;
    }
    if (cnt != y)   return false;
    return true;
}

int main() {
    #ifdef ONLINE_JUDGE
    #else
        freopen("in.txt", "r", stdin);
    #endif
    scanf("%s", st);
    int ans = 0;
    int n = strlen(st) - 1;
//  printf("%d\n", n);
    for (int i = 0; i < (1 << n); ++i) {
        int num = getOne(i);
        if (num != 3)   continue;

        int pos[3], cnt = 0;
        for (int j = 0; j < n; ++j) {
            if (i & (1 << j)) {
                pos[cnt++] = j + 1;
            }
        }
        int a, b, c, d; a = b = c = d = 0;
        for (int j = 0; j < pos[0]; ++j) {
            a = a * 10 + st[j] - '0';
        }
        if (!check(a, pos[0]))  continue;
        for (int j = pos[0]; j < pos[1]; ++j) {
            b = b * 10 + st[j] - '0';
        }
        if (!check(b, pos[1] - pos[0])) continue;
        for (int j = pos[1]; j < pos[2]; ++j) {
            c = c * 10 + st[j] - '0';
        }
        if (!check(c, pos[2] - pos[1])) continue;
        for (int j = pos[2]; j < n + 1; ++j) {
            d = d * 10 + st[j] - '0';
        }
        if (!check(d, (n + 1) - pos[2]))    continue;
//      printf("%d %d %d %d\n", a, b, c, d);
        int flag = (1 << 8);
        if (a < flag && b < flag && c < flag && d < flag) {
            ans++;
        }
    }
    printf("%d\n", ans);
    return 0;
}

D
题意: 判断是不是unicode编码的结果
思路: 模拟即可
这题的答案只有0和1, 从而可以推出你至少可以拿50%的分数, 假设总共100组数据, 答案为0是x组, 那么答案为y是 100 - x, 可知 你能拿的分数 = max(x, 100 - x), 只有当x = 50的时候取到最小值 50

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
// #include 
#include 

using namespace std;

#define LL long long
#define pb push_back
#define mk make_pair
#define pill pair
#define fi first
#define se second
#define mst(a, b) memset(a, b, sizeof a)
#define lson (rt << 1)
#define rson ((rt << 1) | 1)

const int qq = 1e5 + 10;
const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
int num[qq], n;
// LL bits[4];

bool check() {
    if (n == 1) {
        if (num[0] & (1 << 7))  return true;
        return false;
    }
    for (int i = 1; i < n; ++i) {
        if (!(num[i] & (1 << 7)))   return false;
        if (num[i] & (1 << 6))  return false;
    }
    for (int i = 0; i < n; ++i) {
        if (!(num[0] & (1 << (7 - i)))) return false;
    }
    if (num[0] & (1 << (8 - n - 1)))    return false;
    return true;
}

int main() {
    #ifdef ONLINE_JUDGE
    #else
        freopen("in.txt", "r", stdin);
    #endif
    // init();
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) {
        scanf("%d", num + i);
    }
    bool f = true;
    for (int i = 0; i < n && f; ++i) {
        int p = 0;
        if (!(num[i] & (1 << 7))) {
            p = 1;
        } else {
            int start = 7;
            while (start >= 0 && (num[i] & (1 << start)))   start--, p++;
            if (p < 2)  f = false;
            if (p > 4)  f = false;
            if (i + p > n)  f = false;
            for (int j = i + 1; j < i + p; ++j) {
                if (!(num[j] & (1 << 7)))   f = false;
                if (num[j] & (1 << 6))  f = false;
            }
        }
        i += (p - 1);
    }
    int ans = f ? 1 : 0;
    printf("%d\n", ans);
    return 0;
}

E
题意: 求抖音红人
思路: 这题需要前置技能强连通分量. 那么进行缩点形成DAG图以后, 统计出度为0的点的个数, 可以想想如果存在2个及以上的点, 很明显这两个点是互不能到达的. 实际可以看成缩点之后形成了一条链, 才有满足条件的答案. 注意还需要判断联通快的个数

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
// #include 
// #include 

using namespace std;

#define LL long long
#define pb push_back
#define mk make_pair
#define pill pair
#define fi first
#define se second
#define mst(a, b) memset(a, b, sizeof a)
#define lson (rt << 1)
#define rson ((rt << 1) | 1)

const int qq = 2e5 + 10;
const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
int n, m, Bcnt, top, Index;
int fa[qq], dfn[qq], low[qq], Stack[qq], belong[qq], num[qq], deg[qq];
bool instack[qq];
vector<int> vt[qq];
mapbool> mp;
int find(int x) {
    return fa[x] == -1 ? x : fa[x] = find(fa[x]);
}
void tarjan(int u) {
    low[u] = dfn[u] = ++Index;
    instack[u] = true;
    Stack[top++] = u;
    int sz = (int)vt[u].size();
    for (int i = 0; i < sz; ++i) {
        int v = vt[u][i];
        if (!dfn[v]) {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        } else if (instack[v]) {
            low[u] = min(low[u], dfn[v]);
        }
    }
    int v;
    if (low[u] == dfn[u]) {
        ++Bcnt;
        do {
            v = Stack[--top];
            instack[v] = false;
            belong[v] = Bcnt;
            num[Bcnt]++;
        } while (v != u);
    }
}
void init() {
    mst(fa, -1);
    mst(num, 0);
    mst(dfn, 0);
    mst(deg, 0);
    mst(instack, false);
    mp.clear();
    for (int i = 0; i <= n; ++i) {
        vt[i].clear();
    }
}

int main() {
    #ifdef ONLINE_JUDGE
    #else
        freopen("in.txt", "r", stdin);
    #endif
    scanf("%d%d", &n, &m);
    init();
    for (int i = 0, a, b; i < m; ++i) {
        scanf("%d%d", &a, &b);
        if (a > n || b > n) continue;
        if (mp.find(mk(a, b)) != mp.end())  continue;
        mp[mk(a, b)] = true;
        if (a == b) continue; 
        vt[a].pb(b);
        int x = find(a), y = find(b);
        if (x == y) continue;
        fa[y] = x;
    }
    int p = 0;
    for (int i = 1; i <= n; ++i) {
        if (fa[i] == -1)    p++;
    }
    if (p > 1) {
        printf("0\n");
        return 0;
    }
    Bcnt = top = Index = 0;
    for (int i = 1; i <= n; ++i) {
        if (!dfn[i]) {
            tarjan(i);
        }
    }

    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j < (int)vt[i].size(); ++j) {
            int v = vt[i][j];
            if (belong[i] == belong[v]) continue;
            deg[belong[i]]++;
        }
    }
    int cnt = 0, id;
    for (int i = 1; i <= Bcnt; ++i) {
        if (deg[i] == 0)    cnt++, id = i;
    }
    if (cnt == 1) {
        printf("%d\n", num[id]);
    } else {
        printf("0\n");
    }
    return 0;
}

你可能感兴趣的:(线上比赛,笔试,头条)