AtCoder Beginner Contest 369

A - 369

A - 369

思路:分类讨论

#include<bits/stdc++.h>
using namespace std;

#define ull unsigned long long
#define ll long long
#define edl '\n'

const int N = 1e6 + 10;
const int M = 1e3 + 10;

const int mod = 1e9 + 7;
ll n,m,q;
string s;


void solve()
{
	cin >> n >> m;
	if(n == m) cout << 1 << edl;
	else if(abs(n - m) % 2 == 1) cout << 2 << edl;
	else cout << 3 << edl;
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	int t = 1;
//	cin >> t;
	while(t -- ) solve();
	return 0;
}

B - Piano 3

B - Piano 3

思路:模拟

#include<bits/stdc++.h>
using namespace std;

#define ull unsigned long long
#define ll long long
#define edl '\n'

const int N = 1e6 + 10;
const int M = 1e3 + 10;

const int mod = 1e9 + 7;
ll n,m,q;
string s;


void solve()
{
	char ch;
	cin >> n;
	ll sum1,sum2;
	ll ans = 0;
	sum1 = sum2 = -1;
	for(int i = 1; i <= n; i ++ )
	{
		cin >> m >> ch;
		if(ch == 'L')
		{
			if(sum1 != -1) ans += abs(sum1 - m); 
			sum1 = m;
		}
		else
		{
			if(sum2 != -1) ans += abs(sum2 - m); 
			sum2 = m;
		}
	}
	cout << ans << edl;
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	int t = 1;
//	cin >> t;
	while(t -- ) solve();
	return 0;
}

C - Count Arithmetic Subarrays

C - Count Arithmetic Subarrays

思路:双指针,维护以l为起点的等差数列最远到r,统计贡献

#include<bits/stdc++.h>
using namespace std;

#define ull unsigned long long
#define ll long long
#define edl '\n'

const int N = 1e6 + 10;
const int M = 1e3 + 10;

const int mod = 1e9 + 7;
ll n,m,q;
string s;


void solve()
{
	cin >> n;
	vector<ll>a(n + 1,0);
	for(int i = 1; i <= n; i ++ ) cin >> a[i];
	ll l = 1;
	ll r = 1;
	ll ans = 0;
	while(l <= n)
	{
		while(a[l + 1] - a[l] == a[r + 1] - a[r] && r < n) r ++;
		ans += r - l + 1;
		l ++;
	}
	cout << ans << edl;
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	int t = 1;
//	cin >> t;
	while(t -- ) solve();
	return 0;
}

D - Bonus EXP

https://atcoder.jp/contests/abc369/tasks/abc369_d

思路:dp,dp【i】【0】表示到第i个怪兽时,已经打了偶数个怪,dp【i】【1】同理

#include<bits/stdc++.h>
using namespace std;

#define ull unsigned long long
#define ll long long
#define edl '\n'

const int N = 1e6 + 10;
const int M = 1e3 + 10;

const int mod = 1e9 + 7;
ll n,m,q;
string s;


void solve()
{
	cin >> n;
	vector<ll>a(n + 1);
	for(int i = 1; i <= n; i ++ ) cin >> a[i];
	vector dp(n + 1,vector<ll>(2,0));
	for(int i = 1; i <= n; i ++ )
	{
		dp[i][1] = max(dp[i - 1][1],dp[i - 1][0] + a[i]);
		if(dp[i - 1][1]) dp[i][0] = dp[i - 1][1] + a[i] * 2;
		dp[i][0] = max(dp[i - 1][0],dp[i][0]);
	}
	cout << max(dp[n][1],dp[n][0]) << edl;
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	int t = 1;
//	cin >> t;
	while(t -- ) solve();
	return 0;
}

E - Sightseeing Tour

https://atcoder.jp/contests/abc369/tasks/abc369_e

思路:

状压dp+最短路预处理

发现点数较小,可使用n^3的最短路预处理。

发现他给与必须用的桥数量极小,考虑状态压缩dp即可

#include<bits/stdc++.h>
using namespace std;

#define ull unsigned long long
#define ll long long
#define edl '\n'

const int N = 1e6 + 10;
const int M = 1e3 + 10;

const int mod = 1e9 + 7;
ll n,m,q;
string s;

struct QWQ
{
	ll u,v,w;
}a[N];


void solve()
{
	cin >> n >> m;
	vector dp(n + 1,vector<ll>(n + 1,1e17));
	for(int i = 1; i <= m; i ++ )
	{
		cin >> a[i].u >> a[i].v >> a[i].w;
		dp[a[i].u][a[i].v] = min(dp[a[i].u][a[i].v],a[i].w);
		dp[a[i].v][a[i].u] = min(dp[a[i].v][a[i].u],a[i].w);
	}
	for(int k = 1; k <= n; k ++ )
	{
		for(int j = 1; j <= n; j ++ )
		{
			for(int i = 1; i <= n; i ++ )
			{
				if(i == j) dp[i][j] = 0;
				else dp[i][j] = min(dp[i][j],dp[i][k] + dp[k][j]);
			}
		}
	}
	cin >> q;
	while(q -- )
	{
		ll ans = LLONG_MAX;
		ll k;
		cin >> k;
		vector<ll>b(k + 1);
		for(int i = 1; i <= k; i ++ ) cin >> b[i];
		vector an((1LL << k),vector<ll>(n + 1,1e17));
		an[0][1] = 0;
		for(int o = 0; o < (1LL << k); o ++ )
		{
			for(int i = 1; i <= k; i ++ )
			{
				auto [u,v,w] = a[b[i]];
				if(o >> (i - 1) & 1)
				{
					for(int j = 1; j <= n; j ++ )
					{
						an[o][u] = min(an[o][u],an[o ^ (1 << (i - 1))][j] + dp[j][v] + w);
						an[o][v] = min(an[o][v],an[o ^ (1 << (i - 1))][j] + dp[j][u] + w);
					}
				}
			}
		}
		ll o = (1LL << k) - 1;
		for(int i = 1; i <= n; i ++ ) ans = min(ans,an[o][i] + dp[i][n]);
		cout << ans << edl;
	}
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	int t = 1;
//	cin >> t;
	while(t -- ) solve();
	return 0;
}

F - Gather Coins

F - Gather Coins

思路:sort + 树状数组

个人感觉这题比E简单,读完题目你可以发现这题如果再加一个维度就是标准的三维偏序题,显然这里只是二维,因此连cdq都不用直接sort+树状数组即可。

#include<bits/stdc++.h>
using namespace std;

#define ull unsigned long long
#define ll long long
#define edl '\n'

const int N = 1e6 + 10;
const int M = 1e3 + 10;

const int mod = 1e9 + 7;
ll n,m,q;
string s;

struct QWQ
{
	ll x,y;
	ll link;
	ll sum;
}a[N];

bool cmp(QWQ A,QWQ B)
{
	if(A.x != B.x) return A.x < B.x;
	return A.y < B.y;
}

template <typename T>
struct Fenwick {
	int n;
	std::vector<T> a;
	
	Fenwick(int n_ = 0) {
		init(n_);
	}
	
	void init(int n_) {
		n = n_;
		a.assign(n, T{});
	}
	
	void add(int x, T v) {
		for (int i = x + 1; i <= n; i += i & -i) {
			if(v.first > a[i - 1].first) a[i - 1] = v;
		}
	}
	//[0,x)
	T sum(int x) {
		T ans{};
		for (int i = x; i > 0; i -= i & -i) {
			if(a[i - 1].first > ans.first) ans = a[i - 1];
		}
		return ans;
	}
};

Fenwick<pair<ll,ll>>f(N);

void solve()
{
	cin >> n >> m >> q;
	for(int i = 1; i <= q; i ++ )
	{
		cin >> a[i].x >> a[i].y;
		a[i].sum = 1;
	}
	sort(a + 1, a + q + 1,cmp);
	for(int i = 1; i <= q; i ++ ) a[i].link = i;
	for(int i = 1; i <= q; i ++ )
	{
		pair<ll,ll> ok = f.sum(a[i].y + 1);
		if(ok.first != 0)
		{
			a[i].link = ok.second;
			a[i].sum = ok.first + 1;
		}
		f.add(a[i].y,{a[i].sum,i});		
	}
	ll mm = 0;
	ll ck = 0;
	for(int i = 1; i <= q; i ++ )
	{
		if(mm < a[i].sum)
		{
			mm = a[i].sum;
			ck = i;
		}
	}
	vector<ll>ans;
	ans.push_back(ck);
	while(a[ck].link != ck)
	{
		ck = a[ck].link;
		ans.push_back(ck);
	}
	cout << mm << edl;
	ll xx,yy;
	xx = yy = 1;
	for(int i = ans.size() - 1; i >= 0; i -- )
	{
		int x = a[ans[i]].x;
		int y = a[ans[i]].y;
		ll sum = x - xx;
		while(sum --) cout << 'D';
		sum = y - yy;
		while(sum --) cout << 'R';
		xx = x;
		yy = y;
	}
	ll sum = n - xx;
	while(sum --) cout << 'D';
	sum = m - yy;
	while(sum --) cout << 'R';
	cout << edl;
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	int t = 1;
//	cin >> t;
	while(t -- ) solve();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值