小明最近正开发一个料理手游。游戏中仓库里有一些原材料,每个原材料都不相同。在游戏后台,每个原材料由两个不同整数构成。当烹饪锅有至少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;
}