AtCoder Beginner Contest 335 (Sponsored by Mynavi)(c语言+stl)(A~E)(补题)

文章讲述了五种编程竞赛题目中的解题思路和对应的ACCode实现,涉及数组操作、暴力枚举、队列数据结构、构建DAG以及优化算法等IT技术,作者反思了学习方法的局限性。
摘要由CSDN通过智能技术生成

A - 2023

思路:就把最后一位改成4就行了

AC Code

#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
#include <map>
#include <set>
#define ll long long
#define f(i, s, e) for (int i = s; i <= e; i++)
#define ff(i, s, e) for (int i = s; i >= e; i--)
#define maxn (ll)(2e5 + 5000)
using namespace std;
// set<int>::iterator it;
char s[maxn];
int main(void)
{
	scanf("%s", s);
	int t = strlen(s);
	s[t - 1] = '4';
	f(i, 0, t - 1)
	{
		printf("%c", s[i]);
	}

	return 0;
}

B - Tetrahedral Number

思路:就是暴力枚举

AC Code

#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
#include <map>
#include <set>
#define ll long long
#define f(i, s, e) for (int i = s; i <= e; i++)
#define ff(i, s, e) for (int i = s; i >= e; i--)
#define maxn (ll)(2e5 + 5000)
using namespace std;
// set<int>::iterator it;

int main(void)
{
	int n;
	scanf("%d", &n);
	f(i, 0, n)
	{
		f(j, 0, n)
		{
			f(k, 0, n)
			{
				if (i + k + j <= n)
				{
					printf("%d %d %d\n", i, j, k);
				}
			}
		}
	}

	return 0;
}

C - Loong Tracking

思路:维护一个双端队列,根据题意得到一个新的点放进队首,去除队尾

AC Code

#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
#include <map>
#include <set>
#include <utility>
#include <deque>
#include <array>
#define ll long long
#define f(i, s, e) for (int i = s; i <= e; i++)
#define ff(i, s, e) for (int i = s; i >= e; i--)
#define maxn (ll)(2e5 + 5000)
using namespace std;
// set<int>::iterator it;
deque<array<int, 2>> w;
int main(void)
{
	int n, Q;
	scanf("%d%d", &n, &Q);
	f(i, 1, n)
	{
		w.push_back({i, 0});
	}
	int t;
	char te;
	int p;
	int x = 1, y = 0;
	f(i, 1, Q)
	{
		scanf("%d", &t);
		if (t == 1)
		{
			scanf("%s",&te);
			if (te == 'U')
			{
				y++;
			}
			if (te == 'D')
			{
				y--;
			}
			if (te == 'L')
			{
				x--;
			}
			if (te == 'R')
			{
				x++;
			}
			w.pop_back();
			w.push_front({x, y});
		}
		else if (t == 2)
		{
			scanf("%d", &p);
			printf("%d %d\n", w[p - 1][0], w[p - 1][1]);
		}
	}
	return 0;
}

D - Loong and Takahashi

思路:构造一个蛇形数组即可

AC Code

#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
#include <map>
#include <set>
#define ll long long
#define f(i, s, e) for (int i = s; i <= e; i++)
#define ff(i, s, e) for (int i = s; i >= e; i--)
#define maxn (ll)(2e5 + 5000)
using namespace std;
// set<int>::iterator it;
int a[50][50] = {0};
int main(void)
{
	int n;
	scanf("%d", &n);
	int k = 1;
	int x = 1, y = 1;
	int l = n, r = 1;
	while (k < n * n)
	{
		while (a[x][y + 1] == 0 && y < n)
		{
			a[x][y] = k;
			k++;
			y++;
		}
		while (a[x + 1][y] == 0 && x < n)
		{
			a[x][y] = k;
			k++;
			x++;
		}
		while (a[x][y - 1] == 0 && y > 1)
		{
			a[x][y] = k;
			k++;
			y--;
		}
		while (a[x - 1][y] == 0 && x > 1)
		{
			a[x][y] = k;
			k++;
			x--;
		}
	}
	int t = (n + 1) / 2;
	f(i, 1, n)
	{
		f(j, 1, n - 1)
		{
			if (i == t && j == t)
			{
				printf("T ");
				continue;
			}
			else
			{
				printf("%d ", a[i][j]);
			}
		}
		printf("%d\n", a[i][n]);
	}

	return 0;
}

E - Non-Decreasing Colorful Path

思路:根据题意,当小的指向大的时,边权为1,相等时边权为0,可以想到要构造一个DAG(有向无环图),所以要将无向的点缩点,即将边权为0的归为一个集合,最后因为该DAG都是小的指大的,所以只要排一个升序,就是它的拓扑序了,按拓扑序做一次dp即可解决

AC Code

#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#define int long long
#define ll long long
#define f(i, s, e) for (int i = s; i <= e; i++)
#define ff(i, s, e) for (int i = s; i >= e; i--)
#define maxn (ll)(2e5 + 5000)
using namespace std;
int rank1[maxn] = {0};
int fa[maxn] = {0};
int dp[maxn];
int a[maxn] = {0};
vector<int> path;
vector<int> fuck[maxn];
void init(int n)
{
    f(i, 1, n)
    {
        fa[i] = i;
        rank1[i] = 1;
    }
}
int find(int x)
{
    return x == fa[x] ? x : (fa[x] = find(fa[x]));
}
void merge(int i, int j)
{
    int x = find(i);
    int y = find(j);
    if (rank1[x] <= rank1[y])
    {
        fa[x] = y;
    }
    else
    {
        fa[y] = x;
    }
    if (rank1[x] == rank1[y] && x != y)
    {
        rank1[y]++;
    }
}
bool cmp(int x, int y)
{
    return a[x] < a[y];
}
void solve()
{
    int n, m;
    scanf("%lld%lld", &n, &m);
    init(n); // 初始化
    f(i, 1, n)
    {
        dp[i] = -1e18; // 负无穷
        scanf("%lld", &a[i]);
        path.push_back(i);
    }
    int u, v;
    f(i, 1, m)
    {
        scanf("%lld%lld", &u, &v);
        if (a[u] == a[v])
        {
            merge(u, v); // 缩点,构造DAG
        }
        else
        {
            if (a[u] > a[v])
            {
                swap(u, v);
            }
            fuck[u].push_back(v); // 图的存储,表示u->v;
        }
    }
    sort(path.begin(), path.end(), cmp); // 找出拓扑序
    dp[find(1)] = 1;                     // 以1为起点,在i到1之前,都是无意义的,dp[]都为负无穷
    for (auto i : path)
    {
        for (auto j : fuck[i])
        {
            dp[find(j)] = max(dp[find(j)], dp[find(i)] + 1); // 因为i->j,如果dp[find(j)]=dp[find(i)]+1,表示要从i点到j点;
        }
    }
    int ans = 0;
    ans = max(dp[find(n)], ans);
    printf("%lld", ans);
}
signed main(void)
{
    solve();
    return 0;
}

总结:感觉学的太不系统了,唉~~,东学一点,西学一点,捏麻麻滴

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值