I – Interesting Computer Game
题目大意:
• 给了两个数组a与b。
• 第i步可以从a和b中选择一个数。
• 求最后选出的数中,不同的数要最多。
思路:我开始用map来模拟a与b数字的选择,但答案总是错误,实际上应该把不同的数当成图中的点。二元数组a,b当成是一条边,最后构成图,如果转化成图之后有的地方形成了环的话,说明其中的点多次出现,每个都可以取到,对于没有构成环的部分,可能有个点只出现过一次。(利用并查集来解)

#include<iostream>
#include<map>
using namespace std;
const int maxn=1e5+10,maxe=2e5+10;
map<int,int> mp;
int a[maxn],b[maxn];
bool vis[maxe];
int f[maxe],n;

int findfather(int x){
    if(x!=f[x])  f[x]=findfather(f[x]);
    return f[x];
}
void bin()
{
int x,y;
     for(int i=1;i<=n;i++){
            x=findfather(mp[a[i]]),y=findfather(mp[b[i]]);
            if(x!=y){
                f[x]=y;
                if(vis[x]||vis[y])  vis[y]=1,vis[x]=1;
            }
            else  vis[y]=1;
        }
}
int main(){
    int T;
    cin>>T;
    for(int k=1;k<=T;k++){
        int num=1;
       cin>>n;
        for(int i=1;i<=n;i++){
            cin>>a[i]>>b[i];
            if(!mp[a[i]])  mp[a[i]]=num++;
            if(!mp[b[i]])  mp[b[i]]=num++;
        }
        for(int i=1;i<=num;i++)  f[i]=i,vis[i]=0;
        bin();
        int ans=num-1;
        for(int i=1;i<num;i++){
            if(f[i]==i&&vis[i]==0)   ans--;
        }
         cout<<"Case #"<<k<<": "<<ans<<endl;
       mp.clear();
    }
}

I – Interesting Computer Game
题意:
• 有n种菜,每种菜的数量为bi, 每个菜的盈利为 ai。
• 每个顾客必须从第1种菜开始,连续地吃,每种吃一个。
• 保证顾客最多的情况下,盈利最大。
思路:
由题意可以,顾客最多的数量就是b1,而且将b数组处理,后面每一位都比前面的数小,之后就可以比较数组a的前缀和,取出最大的数,因为b数组处理后每一位都比前面的数小,我们从后往前枚举前缀和。因为long long会超出,使用long double。

#include<iostream>
using namespace std;
const int maxn=2e5+10;
typedef long long ll;
int t,n,a[maxn],b[maxn];
long double c[maxn];
int main(){
    cin>>t;
    for(int k=1;k<=t;k++){
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            c[i]=c[i-1]+a[i];
        }
        ll u=c[1];
        a[1]=1;
        for(int i=2;i<=n;i++){
            if(c[i]<=u)    a[i]=0;
            else{
                a[i]=1;
                u=c[i];
            }
        }
        b[0]=1e5+10;
        for(int i=1;i<=n;i++){
           cin>>b[i];
            b[i]=min(b[i-1],b[i]);
        }
        int l=0;
        long double ans=0;
        for(int i=n;i>=1;i--)
            if(a[i]!=0){
                ans+=c[i]*(b[i]-l);
                l=b[i];
            }
       printf("Case #%d: %d %.0Lf\n",k,b[1],ans);

    }
}