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

2023.6.17ABC解题报告

T1

给你一个字符串,每一个字符复制一倍输出。

code

#include <bits/stdc++.h>

#define int long long
#define N 10001000

using namespace std;

int n;

signed main()
{
	cin >> n;
	for(int i = 1; i <= n; i ++)
	{
		char s;
		cin >> s;
		cout << s << s;
	}
	return 0;
}

T2

给你 64 个 0 或 1 的字符,分别代表 \(2^{0}\sim 2^{63}\) 次方,求加起来的和。

直接输入然后用 pow 来计算即可,注意要开 unsigned long long

code:

#include <bits/stdc++.h>

//#define ull unsigned long long
#define int unsigned long long

using namespace std;

int n, ans;

signed main()
{
//	cin >> n;
	for(int i = 0; i <= 63; i ++)
	{
		int c;
		cin >> c;
		if(c == 1) ans += (int) pow(2 , i);
	}
	cout << ans << endl ;
	return 0;
}

T3

给你 3n 个数,里面的 \(1\sim n\) 每个数都会出现三次,按照第二次出现的位置大小来排序,输出排完序的序列。

开一个桶打标记,如果要是当前点是第一次出现就标记为 1,根据这个来判断是不是第二次出现,如果是第二次出现就放入栈中,然后再标记一次,然后把栈里的输出即可。

code

#include <bits/stdc++.h>

#define int long long
#define N 1000100

using namespace std;

int n , a[N] , c[N];
stack <int> q;

signed main()
{
	cin >> n;
	for(int i = 1; i <= 3 * n; i ++) cin >> c[i];
	for(int i = 3 * n; i >= 1; i --)
	{
		if(a[c[i]] == 0) a[c[i]] = 1;
		else if(a[c[i]] == 1) a[c[i]] = 2, q.push(c[i]);
	}
	while(! q.empty() )
	{
		cout << q.top() << ' ';
		q.pop();
	}
	return 0;
}

T4

一看就知道是 DP。

我写出来了但是写麻烦了。

我的思路是用 \(f[i][j]\) 表示当前到 \(i\) 对于状态 \(j\) 来说的最大得分,\(j\) 只有两种情况,0 代表健康 1 是胃不舒服。

很容易想到当当前食物是有毒的话,可以从之前中毒转移到当前点的中毒,不吃,吃了就死了所以不能吃,也可以从健康吃了变成有毒,也可以不吃还是健康。

如果当前食物无毒的话,我们可以从之前无毒或者有毒吃了这个食物转移过来,或者无毒不吃转移过来,我们也可以从之前中毒不吃这个食物转移到当前状态中毒。

code:

#include <bits/stdc++.h>

#define int long long
#define N 1000100

using namespace std;

int n, a[N], op[N], f[N][2];//0是健康,1是中毒,

signed main()
{
	cin >> n;
	for(int i = 1; i <= n; i ++)
		cin >> op[i] >> a[i];
	for(int i = 1; i <= n; i ++)
	{
		if(op[i] == 1)
		{
			f[i][1] = max(f[i][1], f[i - 1][1]);
			f[i][1] = max(f[i][1], f[i - 1][0] + a[i]);
			f[i][0] = max(f[i][0], f[i - 1][0]);
		}
		if(op[i] == 0)
		{
			f[i][1] = max(f[i][1], f[i - 1][1]);
			f[i][0] = max(f[i][0], f[i - 1][1] + a[i]);
			f[i][0] = max(f[i][0], f[i - 1][0] + a[i]);
			f[i][0] = max(f[i][0], f[i - 1][0]);
		}
	}
	cout << max(f[n][0], f[n][1]) << endl;
	return 0;
}

有个老哥写了个更简单的:

#include <cstdio>
#include <algorithm>
using namespace std;

using LL = long long;

int main()
{
    LL f = 0LL, g = 0LL;
    int n;
    scanf("%d", &n);
    while(n--)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        if(x == 0) f = max(f, max(f, g) + y);
        else g = max(g, f + y);
    }
    printf("%lld\n", max(f, g));
    return 0;
}

其实就是 f 存放健康,g 存放中毒

健康可以是之前中毒或者健康转移,中毒只能是从健康变成中毒。

posted @ 2023-06-17 22:37  北烛青澜  阅读(4)  评论(0编辑  收藏  举报