//https://img2018.cnblogs.com/blog/1646268/201908/1646268-20190806114008215-138720377.jpg

2023.7.8ABC

2023.7.8ABC

A

一个按顺序填好的九宫格,问你里面两个数是不是水平相邻。

只要判断是不是同一行就过了。

#include <bits/stdc++.h>

#define int long long
#define N 100100

using namespace std;

signed main()
{
	int x, y;
	cin >> x >> y;
	if((x - 1) / 3 != (y - 1) / 3) cout << "No" << endl;
	else cout << "Yes" << endl;
	return 0;
}

B

给你一个矩阵,把最外圈的元素都顺时针转一个单位然后输出。

纯模拟,恶心你的。

#include <bits/stdc++.h>

#define int long long
#define N 1010

using namespace std;

int n, a[N][N], b[N][N];
 
signed main()
{
	cin >> n;
	for(int i = 1; i <= n; i ++)
		for(int j = 1; j <= n; j ++)
			scanf("%1lld", &a[i][j]), b[i][j] = a[i][j];
	b[1][1] = a[2][1]; b[n][n] = b[n - 1][n];
	for(int i = 2; i <= n; i ++)
		b[1][i] = a[1][i - 1],
		b[i][n] = a[i - 1][n];
	for(int i = n - 1; i >= 1; i --)
		b[n][i] = a[n][i + 1],
		b[i][1] = a[i + 1][1];
	for(int i = 1; i <= n; i ++)
	{
		for(int j = 1; j <= n; j ++)
			cout << b[i][j];
		cout << endl;
	}
	return 0;
}

C

一共 \(n\) 种药,一个 \(k\),一个药一天吃 \(b_{i}\) 片,第 \(a_{i} + 1\) 天开始就不能吃这个药了,问你你第几天吃的药数量小于 \(k\)

我们记录每一个药的信息,然后按天从小到大排序,用 \(sum\) 表示总的药片数量,然后如果减去当前天就不能到 \(k\) 了就记录答案是 \(a_{i} + 1\) ,直接输出即可,还有就是特判一开始 \(sum \le k\) 的情况。

#include <bits/stdc++.h>

#define int long long
#define N 1000100

using namespace std;

int n, k, ans, sum;
struct sb{int id, v;}e[N];

inline int cmp(sb a, sb b) 
{
	if(a.id == b.id)return a.v > b.v;
	return a.id < b.id;
}

signed main()
{
	cin >> n >> k;
	for(int i = 1; i <= n; i ++)
		cin >> e[i].id >> e[i].v, sum += e[i].v;
	if(sum <= k) return cout << "1" << endl, 0;
	sort(e + 1, e + n + 1, cmp);
	for(int i = 1; i <= n; i ++)
	{
		if(sum - e[i].v <= k){ans = e[i].id + 1;break;}
		sum -= e[i].v;
	}
	cout << ans << endl;
	return 0;
}

D

两个连通图,让你加一条边,让 \(1\sim n_{1} + n_{2}\) 的路径长度最长。

直接从两个点跑最短路,取最大的 \(dis\) 然后加 \(1\) 即可。

#include <bits/stdc++.h>

#define pii pair<int, int>
#define int long long
#define N 1000100

using namespace std;

int n1, n2, m, dis[N], ans1, ans2;
vector<int> e[N];
bitset<N> vis;

inline void dij(int s, int l, int r)
{
    priority_queue<pii, vector<pii>, greater<pii> > q;
    for (int i = l; i <= r; ++ i) dis[i] = 1e18;
    dis[s] = 0;
    q.push({0, s});
    while(!q.empty())
	{
        int u = q.top().second;
        q.pop();
        if(vis[u]) continue ;
        vis[u] = 1;
        for(int v : e[u])
            if (dis[v] > dis[u] + 1)
                dis[v] = dis[u] + 1, q.push({dis[v], v});
    }
    return ;
}

signed main()
{
    cin >> n1 >> n2 >> m;
    for (int i = 1; i <= m; i ++)
	{
		int u, v;
        cin >> u >> v;
        e[u].push_back(v);
        e[v].push_back(u);
    }
    dij(1, 1, n1);
    dij(n1 + n2, n1 + 1, n1 + n2);
    for(int i = 1; i <= n1; i ++)
    	ans1 = max(ans1, dis[i]);
    for(int i = n1 + 1; i <= n1 + n2; i ++)
        ans2 = max(ans2, dis[i]);
    cout << ans1 + ans2 + 1 << endl;
    return 0;
}

E

一堆人,一堆保险,一个保险能覆盖两代人,求覆盖人数最多的保险是多少人。

直接 dfs 的时候处理 dep 然后输出最大值即可。

#include <bits/stdc++.h>

#define int long long
#define N 1000100

using namespace std;

int n, m, fa, ans, bx[N], cnt, head[N];
struct sb{int u, v, next;}e[N];

inline void add(int u, int v) {e[++ cnt] = {u, v, head[u]}; head[u] = cnt;}

inline void dfs(int u)
{
    for(int i = head[u]; i; i = e[i].next)
	{
		int v = e[i].v;
        bx[v] = max(bx[v], bx[u] - 1);
        dfs(v);
    }
    return ;
}

signed main()
{
    cin >> n >> m;
    for(int i = 2; i <= n; i ++)
        cin >> fa, add(fa, i);
    for(int i = 1; i <= m; i ++)
	{
		int u, v;
        cin >> u >> v;
        bx[u] = max(bx[u], v + 1);
    }
    dfs(1);
    for(int i = 1; i <= n; i ++)
        if(bx[i]) ans ++;
    cout << ans << endl;
    return 0;
}
posted @ 2023-07-08 22:39  北烛青澜  阅读(3)  评论(0)    收藏  举报