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

    A题 喵哈哈村的数据筛选游戏

    题解:这道题签到题,拿个数组记录一下这个数是否出现过即可。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5+5;
    int vis[maxn];
    int n;
    int a[maxn];
    int main(){
        while(cin>>n){
            memset(vis,0,sizeof(vis));
            for(int i=0;i<n;i++){
                cin>>a[i];
            }
            int flag = 0;
            for(int i=0;i<n;i++){
                if(vis[a[i]]==0){
                    vis[a[i]]=1;
                    if(flag==0){
                        cout<<a[i],flag=1;
    
                    }
                    else cout<<" "<<a[i];
                }
            }
            cout<<endl;
        }
    }
    

    B题:喵哈哈村的扔硬币游戏

    题解:直接暴力更新应该也能过,这里我提倡一种前缀和的做法,每次操作的时候只要看这个点被更新了奇数次还是偶数次就好了。

    前缀和的具体方式看代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 1e5+7;
    
    int a[maxn];
    
    int main(){
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            int A,B;
            scanf("%d%d",&A,&B);
            a[A]++;
            a[B+1]--;
        }
        int sum = 0;
        for(int i=1;i<=n;i++){
            sum+=a[i];
            if(sum%2==0)printf("0");
            else printf("1");
        }
        printf("
    ");
    }
    

    C题:喵哈哈村的三角形游戏

    三角插值实际上就是假设三个顶点为p1,p2,p3,那么所有三角形内的点都满足

    p.x = ap1.x+bp2.x+cp3.x;
    p.y = a
    p1.y+bp2.y+cp3.y;
    a+b+c = 1

    解这个方程得到a,b,c

    然后再算p.w = ap1.w+bp2.w+c*p3.w即可。

    判断是否在三角形内部,用计算几何的叉积或者面积法都可以。

    #include<bits/stdc++.h>
    using namespace std;
    const double eps = 1e-6;
    double x1,yy1,z1,x2,y2,z2,x3,y3,z3;
    double x,y;
    struct node{
        double x,y;
        double w;
    }p[5];
    double dis(node A,node B){
        return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
    }
    
    double area(node A,node B,node C){
        double len1 = dis(A,B),len2 = dis(B,C),len3 = dis(A,C);
        double p = (len1+len2+len3)/2;
        return sqrt(p*(p-len1)*(p-len2)*(p-len3));
    }
    bool equ(double A,double B){
        if(fabs(A-B)<eps)return true;
        return false;
    }
    int main(){
        while(cin>>p[0].x>>p[0].y>>p[0].w){
            for(int i=1;i<3;i++)
                cin>>p[i].x>>p[i].y>>p[i].w;
            cin>>p[3].x>>p[3].y;
            for(int i=3;i>=0;i--){
                p[i].x-=p[0].x;
                p[i].y-=p[0].y;
            }
            if(equ(area(p[0],p[1],p[2]),area(p[0],p[1],p[3])+area(p[0],p[2],p[3])+area(p[1],p[2],p[3]))==false){
                cout<<"-1"<<endl;
                continue;
            }
            double B = (p[1].x*p[3].y-p[3].x*p[1].y)/(p[1].x*p[2].y-p[2].x*p[1].y);
            double A;
            if(equ(p[1].x,0)==false)A = (p[3].x-B*p[2].x)/p[1].x;
            else A = (p[3].y-B*p[2].y)/p[1].y;
            printf("%.2f
    ",A*p[1].w+B*p[2].w+(1.0-A-B)*p[0].w);
        }
    }
    

    D:喵哈哈村的修路游戏

    答案显然为连通块的数量-1,随便拿个东西算连通块的数量就好了。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e3+7;
    vector<int> E[maxn];
    int n,m;
    int vis[maxn],cnt=0;
    void dfs(int x){
        vis[x]=1;
        for(int i=0;i<E[x].size();i++){
            if(!vis[E[x][i]])
                dfs(E[x][i]);
        }
    }
    int main(){
        cin>>n>>m;
        for(int i=0;i<m;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            E[a].push_back(b);
            E[b].push_back(a);
        }
        for(int i=1;i<=n;i++){
            if(!vis[i]){
                cnt++;
                dfs(i);
            }
        }
        cout<<cnt-1<<endl;
    }
    

    E:喵哈哈村的打印机游戏

    区间DP,dp[l][r][d]表示区间[l,r],当前底色为d的最小花费。

    然后枚举中间的节点进行转移就好了,具体看代码,是一道中规中矩的区间DP题目。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 106;
    int dp[maxn][maxn][maxn];
    const int inf = 1e8;
    string s;
    int solve(int l,int r,int d){
        if(l>r)return 0;
        if(s[l]-'A'==d&&l==r)return dp[l][r][d]=0;
        if(l==r)return dp[l][r][d]=1;
        if(dp[l][r][d]!=-1)return dp[l][r][d];
        dp[l][r][d]=inf;
        for(int i=0;i<26;i++){
            dp[l][r][d]=min(dp[l][r][d],solve(l,r,i)+1);
        }
        if(s[l]-'A'==d)dp[l][r][d]=min(dp[l][r][d],solve(l+1,r,d));
        if(s[r]-'A'==d)dp[l][r][d]=min(dp[l][r][d],solve(l,r-1,d));
        for(int i=l+1;i<r;i++){
            if(s[i]-'A'==d){
                dp[l][r][d]=min(dp[l][r][d],solve(l,i-1,d)+solve(i+1,r,d));
            }
        }
        return dp[l][r][d];
    }
    int main(){
        while(cin>>s){
            memset(dp,-1,sizeof(dp));
            cout<<solve(0,s.size()-1,27)<<endl;
        }
    }
  • 相关阅读:
    图的m着色问题 (回溯搜索)
    部落卫队 (回溯搜索)
    子集和问题 (回溯搜索)
    有重复元素的排列问题
    分书 回溯搜索
    选择工作 回溯搜索
    Problem E 
    Problem B
    Problem A
    Problem A
  • 原文地址:https://www.cnblogs.com/qscqesze/p/6591517.html
Copyright © 2011-2022 走看看