题解:P10191 [USACO24FEB] Test Tubes S
题解:P10191 [USACO24FEB] Test Tubes S
思路
主打一个乱搞。
首先烧杯应该只有 1 种液体,因为总共就有两种液体,并且要将液体合并,所以应尽量合并液体,而且因为有三个容器,所以我们每次选择容器顶部相同的两种液体合并即可。
先想想边界条件,如果两个试管都只剩一种液体那么操作就结束了,不过记得判断烧杯里有没有液体,如果还有就倒入液体相同的试管。
再判断如果有试管空了,则将另一个试管内的液体倒进去,并且还要特判,如果另一个试管内只有一种液体,则直接将烧杯内的液体倒入空试管,操作就结束了。
然后判断哪两个容器顶部液体相同即可,如果两个试管液体相同,则将液体数量多的试管的液体倒入液体数量少的试管。
接下来要么是试管液体和烧杯液体一样,则将试管液体倒入烧杯,否则烧杯为空的话,就将液体数量多的试管的液体倒入烧杯即可。
代码
怎么没看见有人用 unique 去重?
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int t,n,P,a[100010],b[100010],ai,bi;
struct N{int x,y;
};
int main(){ios::sync_with_stdio(0);cin.tie(0);cin>>t;while(t--){cin>>n>>P;ai=bi=n;char c;for(int i=1,x;i<=n;i++){cin>>c; a[i]=c-'0';}ai=unique(a+1,a+1+ai)-a-1;//使用unique去重 for(int i=1,x;i<=n;i++){cin>>c; b[i]=c-'0';}bi=unique(b+1,b+1+bi)-b-1;int ci=0;vector<N> v; while(1){if(ai==1&&bi==1&&a[ai]!=b[bi]){//如果两个试管内都只有一种液体 if(a[ai]==ci){v.push_back({3,1}); ci=0;}if(b[bi]==ci){v.push_back({3,2}); ci=0;}break;}if(ai==0){//如果第一个试管为空 if(bi==1){v.push_back({3,1}); break;}else{a[++ai]=b[bi--]; v.push_back({2,1});}}else if(bi==0){//如果第二个试管为空 if(ai==1){v.push_back({3,2}); break;}else{b[++bi]=a[ai--]; v.push_back({1,2});}}else if(ai&&bi&&a[ai]==b[bi]){//如果两个试管顶部液体相等 if(ai>bi){ai--; v.push_back({1,2});}else{bi--; v.push_back({2,1});}}else{if(ci==0){//如果烧杯为空 if(ai>bi){v.push_back({1,3}); ci=a[ai--];}else{v.push_back({2,3}); ci=b[bi--];}}else if(ai&&a[ai]==ci){v.push_back({1,3}); ai--;}//如果第一个试管顶部液体与烧杯液体相同 else if(bi&&b[bi]==ci){v.push_back({2,3}); bi--;}//如果第二个试管顶部液体与烧杯液体相同 }}cout<<v.size()<<'\n';if(P-1)for(N i:v)cout<<i.x<<" "<<i.y<<'\n';//输出 }return 0;
}