zoukankan      html  css  js  c++  java
  • 喵哈哈村的魔法考试 Round #10 (Div.2) 题解

    喵哈哈村与哗啦啦村的大战(一)

    最大值就是全部+3,最小值就是全部-3,注意不能降为负数。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 105;
    int a[maxn],n;
    int main(){
        while(cin>>n){
            int ans1=0,ans2=0;
            for(int i=0;i<n;i++){
                cin>>a[i];
                ans1+=a[i]+3;
                ans2+=max(0,a[i]-3);
            }
            cout<<ans1<<" "<<ans2<<endl;
        }
    }
    

    喵哈哈村与哗啦啦村的大战(二)

    最优答案就是摆成等边三角形,所有点均分过去,使得每个点都在无限靠近三角形的顶点位置。

    那么最少摧毁(n+2)/3个点了。

    #include<bits/stdc++.h>
    using namespace std;
    
    int main(){
        long long n;
        while(cin>>n){
            cout<<(n+2LL)/3LL<<endl;
        }
    }
    

    喵哈哈村与哗啦啦村的大战(三)

    考虑贪心,我们统计所有的和之后,我们每次选择ci最小的,即花费最小的进行操作。

    然后不停使得和向着s靠拢,如果最后能靠拢的话,就输出答案,否则就输出impossible。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e6+6;
    const int inf = 1e9+7;
    int dp[maxn],a[maxn],c[maxn],l[maxn],r[maxn];
    vector<pair<int,int> > sp[2];
    int main(){
        int n,s;
        while(scanf("%d%d",&n,&s)!=EOF){
            sp[0].clear();
            sp[1].clear();
            for(int i=1;i<=n;i++){
                scanf("%d%d%d%d",&a[i],&c[i],&l[i],&r[i]);
            }
            int sum1=0,sum2=0,sum3=0;
            for(int i=1;i<=n;i++){
                sum1+=l[i];
                sum2+=a[i];
                sum3+=r[i];
                sp[0].push_back(make_pair(c[i],r[i]-a[i]));
                sp[1].push_back(make_pair(c[i],a[i]-l[i]));
            }
            if(sum1>s){
                cout<<"impossible"<<endl;
                continue;
            }
            if(sum3<s){
                cout<<"impossible"<<endl;
                continue;
            }
            int order = 0;
            if(s>=sum2)order=0;
            else order=1;
            int sum4=abs(s-sum2);
            int ans=0;
            sort(sp[order].begin(),sp[order].end());
            for(int i=0;i<sp[order].size();i++){
                if(sum4>0){
                    int d=min(sum4,sp[order][i].second);
                    sum4-=d;
                    ans+=d*sp[order][i].first;
                }
            }
            cout<<ans<<endl;
        }
    }
    

    喵哈哈村与哗啦啦村的大战(四)

    树形dp

    维护dp1[i]表示从下到上大于等于的序列个数。

    维护dp2[i]表示从下到上小于等于的序列个数。

    这两者相乘,就是好序列的个数。

    但是这有重复的项,因为都统计了相等的,所以得减去相等的与相等的之乘积。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5+7;
    vector<pair<int,int> >E[maxn];
    int n,a[maxn];
    long long Down[maxn],Up[maxn],Down2[maxn],Up2[maxn];
    long long equ[maxn];
    long long ans = 0;
    void dfs(int x,int fa){
        Down[x]=1;
        Up[x]=1;
        Down2[x]=1;
        Up2[x]=1;
        equ[x]=1;
        long long sumup,sumdown,sumequ;
        for(int i=0;i<E[x].size();i++){
            int v = E[x][i].second;
            if(v==fa)continue;
            dfs(v,x);
            if(a[x]>=a[v]){
                Down[x]+=Down[v];
            }
            if(a[x]<=a[v]){
                Up[x]+=Up[v];
            }
            if(a[x]==a[v]){
                equ[x]+=equ[v];
            }
        }
        sumup=Up[x];
        sumdown=Down[x];
        sumequ=equ[x];
        for(int i=0;i<E[x].size();i++){
            int v = E[x][i].second;
            if(v==fa)continue;
            if(a[x]<=a[v]){
                sumup-=Up[v];
            }
            if(a[x]>=a[v]){
                sumdown-=Down[v];
            }
            if(a[x]==a[v]){
                sumequ-=equ[v];
            }
            if(a[x]>=a[v])
                ans+=Down[v]*sumup;
            if(a[x]<=a[v])
                ans+=Up[v]*sumdown;
            if(a[x]==a[v])
                ans-=equ[v]*sumequ;
        }
    }
    int main(){
        while(scanf("%d",&n)!=EOF){
            ans=0;
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]),E[i].clear();
            for(int i=1;i<n;i++){
                int A,B;
                scanf("%d%d",&A,&B);
                E[A].push_back(make_pair(a[i],B));
                E[B].push_back(make_pair(a[i],A));
            }
            for(int i=1;i<=n;i++)
                sort(E[i].begin(),E[i].end());
            dfs(1,-1);
            cout<<ans<<endl;
        }
    }
    

    喵哈哈村与哗啦啦村的大战(五)

    假设现在考虑到第i个数,第i个数是12=223,那么m[j]统计前i-1个数,前缀为j的个数。

    那么gcp为2的答案就是m[2]-m[4]

    看懂这个这道题就简单了,自己写就好了。

    #include<bits/stdc++.h>
    using namespace std;
    
    map<int,int> H;
    int n;
    int a[100005];
    int main(){
        while(cin>>n){
            H.clear();
            for(int i=0;i<n;i++)
                scanf("%d",&a[i]);
            long long ans = 0;
            for(int i=0;i<n;i++){
                vector<int>tmp;
                int now=1;
                tmp.push_back(now);
                for(int j=2;j*j<=a[i];j++){
                    while(a[i]%j==0){
                        now*=j;
                        tmp.push_back(now);
                        a[i]/=j;
                    }
                }
                if(a[i]!=1){
                    now*=a[i];
                    tmp.push_back(now);
                }
                reverse(tmp.begin(),tmp.end());
                long long sum = 0;
                for(int j=0;j<tmp.size();j++){
                    ans+=1ll*tmp[j]*(1ll*H[tmp[j]]-sum);
                    sum=H[tmp[j]];
                    H[tmp[j]]++;
                }
            }
            cout<<ans<<endl;
        }
    }
  • 相关阅读:
    测试开发知识体系
    渗透测试全套教程(从原理到实战)
    解决edittext输入多行可以滑动的问题
    SharedPreferences实现自动登录记住用户名密码
    listview当选中某一个item时设置背景色其他的不变
    转 -android:程序无响应,你该如何定位问题?
    区分listview的item和Button的点击事件
    转--2014年最新810多套android源码2.46GB免费一次性打包下载
    转-android 支付宝SDK集成
    转-封装网络请求库,统一处理通用异常 (基于volley网络请求库)
  • 原文地址:https://www.cnblogs.com/qscqesze/p/6635326.html
Copyright © 2011-2022 走看看