PTA黑暗料理

文章描述了一个关于料理手游中的问题,玩家需要在输入原材料到烹饪锅的过程中,遵循规则避免触发黑暗料理。通过使用并查集算法,找出原材料之间的关系并计算出在不违反规则下最小丢弃次数。给出的C++代码展示了如何运用并查集实现这一目标。
摘要由CSDN通过智能技术生成

小明最近正开发一个料理手游。游戏中仓库里有一些原材料,每个原材料都不相同。在游戏后台,每个原材料由两个不同整数构成。当烹饪锅有至少N(N≥2)个原材料且其中有N个原材料正好包含N个不同的整数(即这N个整数每个出现了2次),那么此时将触发黑暗料理。比如烹饪锅中有原材料(1,2),(2,3),(3,1)时,将触发黑暗料理。
现在传送带按输入顺序将仓库里原材料放入烹饪锅,玩家可以将还在传送带上尚未进入烹饪锅的原材料拖出丢弃。(玩家不能改变原材料顺序)当玩家保证不会出现黑暗料理的情况下,需要丢弃原材料的最小个数是多少呢?

输入格式:

包含多组数据。每组数据包含若干行,每行为两个不同的整数a,b,表示某一种原材料( 0≤a,b≤105)。所有原材料按照进入烹饪锅的先后顺序排列。每组数据用一行-1结尾。输入结束标志为文件结束符(EOF)。

输出格式:

保证不会出现黑暗料理的情况下,玩家需丢弃原材料的最小个数。

输入样例:

1 2
2 3
3 1
-1
1 2
2 3
1 4
-1

输出样例:

1
0

 单纯吐槽一下,这居然是个并查集题目。

照题目写有n个数个数为2:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl "\n"

ll n,m;
map<ll,ll>mp;
stack<pair<ll,ll> >st;

int main(){
	ll x,y,c=0,sum=0,g=0;
	while(cin >> x){
		if(x == -1){
			cout << sum << endl;
			mp.clear();
			sum=0,c=0;
			while(!st.empty())st.pop();
			continue;
		}
		cin >> y;
		c++;
		mp[x]++,mp[y]++;
		st.push({x,y});
		while(mp.size() == c && c > 1){
			x=st.top().first,y=st.top().second;
			st.pop();
			sum++,mp[x]--,mp[y]--,c--;
			if(mp[x] == 0)mp.erase(x);
			if(mp[y] == 0)mp.erase(y);
		}
	}
	return 0;
}

结果:

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl "\n"

const ll N = 1e5+7;
ll n,m;
ll v[N];

ll find(ll x){
	if(v[x] == x)return x;
	return v[x]=find(v[x]);
}

void bing(ll x ,ll y){
	ll tx=find(x),ty=find(y);
	if(tx > ty)swap(tx,ty);
	v[ty]=tx;
}

void solve(){
	ll x,y,sum=0;
	for(ll i = 0 ; i < N ; i ++)v[i]=i;
	while(cin >> x){
		if(x == -1){
			cout << sum << endl;
			for(ll i = 0 ; i < N ; i ++)v[i]=i;
			sum=0;
			continue;
		}
		cin >> y;
		if(find(x) == find(y))sum++;
		else bing(x,y);
	}
	return;
}

int main(){
	ll t=1;//cin >> t;
	while(t--)solve();
	return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值