[算法学习记录][题解] ABC398 A-D

A - Doors in the Center

当n为奇数时,输出一个'=';
当n为偶数时,输出两个'=';
在等号前后各输出(n-1)/2个'-';

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

void solve()
{
	int n;cin >> n;
	for(int i = 1;i<=(n - 1)/2;i++)	cout << '-';
	if(n%2==0)cout << "==";
	else cout << "=";
	for(int i = 1;i<=(n - 1)/2;i++)	cout << '-' ;
}

int main()
{
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	int _ = 1;
	while(_--)solve();
	return 0;
}

B - Full House 3

利用桶排的思想,把所有的a[i]都对到桶里再进行升序排序,检查最后一个是否大于3,倒数第二个是否大于2即可。

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 14;
int t[N];

void solve()
{
	for(int i = 1;i<=7;i++)
	{
		int x;cin >> x;
		t[x]++;
	}
	
	sort(t+1,t+1+13);
	
	if(t[13]>=3&&t[12]>=2)cout << "Yes\n";
	else cout << "No\n";
}

int main()
{
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	int _ = 1;
	while(_--)solve();
	return 0;
}

C - Uniqueness

由于a[i]的值较大数组可能存不下,所以不能向B题一样使用桶,我们可以选择map来记录个数字的出现次数,并记录下它们第一次出现时的坐标,最后遍历map并找出最大值的坐标即可。

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll N = 3e5 + 5;
ll a[N];

struct Edge
{
	ll x, y;
};
map<ll, Edge>mp;
//用一个结构体来存储一个数的值以及他第一次出现时的坐标 
void solve()
{
	ll n; cin >> n;
	for (ll i = 1; i <= n; i++)cin >> a[i];
	
	for (ll i = 1; i <= n; i++)
	{
		if (mp.count(a[i]) == 0)
		{
			mp[a[i]].x = 1;
			mp[a[i]].y = i;
		}
		else mp[a[i]].x++;
	}
	
	ll ans = -1;
	for (auto m : mp) if (m.second.x == 1) ans = max(ans, m.first);
	cout << (ans == -1 ? -1 : mp[ans].y) << "\n";
	//如果ans = -1,说明不存在只有一个的数,否则就输出这个数的坐标 
}

int main()
{
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	int _ = 1;
	while (_--)solve();
	return 0;
}

D - Bonfire

如果移动烟雾,随着时间的推移,每次要移动的烟雾就会越来越多,且N(移动次数)的大小在2e5,这样时间复杂的就会变得非常大,不可取;
我们不妨把思维逆转过来,考虑移动篝火和高桥,篝火每移动一次就会在原地留下一团烟,这样我们每次只需移动两个物体,不过移动时要注意篝火和高桥移动的方向与烟雾相反。
我们可以用set记录下篝火曾移动过的坐标,这样就免去了去重操作。
在移动操作完成后,我们对set进行遍历

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int n,r,c,x,y;
string S;

set<pair<int ,int>> st;
//创建一个set来存储烟雾的位置,用pair来存储坐标 
void solve()
{
	cin >> n >> r >> c >> S;

	st.insert({0,0});
	//篝火的起始位置 
	for(auto ch : S)
	{
		if(ch == 'N') x++,r++; 
		else if(ch == 'W') y++,c++;
		else if(ch == 'S') x--,r--;
		else if(ch == 'E') y--,c--;
		//移动篝火和高桥 
		st.insert({x,y});
		//把结果放入集合中
		cout << st.count({r,c});	
	}
}

int main()
{
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	int _ = 1;
	while(_--)solve();
	return 0;
}

反向思维。

本人初学算法,文章难免有纰漏,如若发现,敬请指正。

posted @ 2025-03-23 14:37  林克还是克林  阅读(47)  评论(0)    收藏  举报