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

    喵哈哈村的美食面馆

    签到题,就不停的if就好了。

    #include<bits/stdc++.h>
    using namespace std;
    
    string name[5]={"niuroumian","zajiangmian","jiandanmian","fangbianmian","roujiamo"};
    int p[5][3]={{8,10,12},{7,9,11},{8,10,12},{3,5,7},{4,5,6}};
    int main(){
        int n;
        while(cin>>n){
            int ans = 0;
            for(int i=0;i<n;i++){
                string op;
                int sz;
                cin>>op>>sz;
                for(int j=0;j<5;j++){
                    if(name[j]==op){
                        ans+=p[j][sz];
                    }
                }
            }
            cout<<ans<<endl;
        }
    }
    

    喵哈哈村的炒饭馆

    这道题也是签到题,错误的原因大概就是没有读题?或者读错题了?

    每场比赛的胜利方得到三分,失败方0分,平局双方都加一分。

    最后再扫一遍最大值,然后按照字典序输出就好了。

    #include<bits/stdc++.h>
    using namespace std;
    
    int p[55];
    string s[55];
    int main(){
        int n;scanf("%d",&n);
        for(int i=0;i<n;i++){
            cin>>s[i];
        }
        vector<pair<int,int> >V;
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(j==i)continue;
                if(s[i][j]=='W'){
                    p[i]+=3;
                }
                if(s[i][j]=='L'){
                    p[j]+=3;
                }
                if(s[i][j]=='D'){
                    p[i]+=1;
                    p[j]+=1;
                }
            }
        }
        for(int i=0;i<n;i++){
            V.push_back(make_pair(p[i],i));
        }
        sort(V.begin(),V.end());
        reverse(V.begin(),V.end());
        vector<int> ans;
        for(int i=0;i<V.size();i++){
            if(V[i].first == V[0].first)
                ans.push_back(V[i].second);
        }
        sort(ans.begin(),ans.end());
        printf("%d",ans[0]+1);
        for(int i=1;i<ans.size();i++){
            printf(" %d",ans[i]+1);
        }
        printf("
    ");
    }
    

    喵哈哈村的黄焖鸡

    我说一下我的做法:

    因为除了0和n-1两个点,每个点只能经过一次,那么这个点要么在过去的路上,要么就在回来的路上。

    我们实际上可以把过去和回来的两条路都当成过去的,然后我们就考虑这个点究竟是接在第一条路后面,还是接在第二条路的后面。

    那么我们用一个dp来维护吧,dp[i][j][k][2][2]表示考虑到第i个点,第一条路的上一个点是j,第二条路得上一个点是k,第一条路是否经过a,第二条路是否经过b。

    然后维护dp即可,滚动维护第一维。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1050;
    double dp[2][maxn][maxn][2][2];
    struct node{
        double x,y;
    }p[maxn];
    int n,a,b;
    double cal(int x,int y){
        return sqrt((p[x].x-p[y].x)*(p[x].x-p[y].x)+(p[x].y-p[y].y)*(p[x].y-p[y].y));
    }
    int main(){
        scanf("%d%d%d",&n,&a,&b);
        for(int i=0;i<n;i++){
            cin>>p[i].x>>p[i].y;
        }
        int now=0,pre = 1;
        dp[now][0][0][0][0]=0;
        dp[now][0][0][0][1]=1e15;
        dp[now][0][0][1][0]=1e15;
        dp[now][0][0][1][1]=1e15;
        for(int i=1;i<n-1;i++){
            swap(now,pre);
            for(int j=0;j<n;j++){
                for(int k=0;k<n;k++){
                    dp[now][j][k][0][0]=1e15;
                    dp[now][j][k][0][1]=1e15;
                    dp[now][j][k][1][0]=1e15;
                    dp[now][j][k][1][1]=1e15;
                }
            }
            for(int j=0;j<i;j++){
                for(int k=0;k<i;k++){
                    dp[now][i][k][0][0]=min(dp[now][i][k][0][0],dp[pre][j][k][0][0]+cal(j,i));
                    dp[now][j][i][0][0]=min(dp[now][j][i][0][0],dp[pre][j][k][0][0]+cal(k,i));
                    dp[now][i][k][1][0]=min(dp[now][i][k][1][0],dp[pre][j][k][1][0]+cal(j,i));
                    dp[now][j][i][1][0]=min(dp[now][j][i][1][0],dp[pre][j][k][1][0]+cal(k,i));
                    dp[now][i][k][0][1]=min(dp[now][i][k][0][1],dp[pre][j][k][0][1]+cal(j,i));
                    dp[now][j][i][0][1]=min(dp[now][j][i][0][1],dp[pre][j][k][0][1]+cal(k,i));
                    dp[now][i][k][1][1]=min(dp[now][i][k][1][1],dp[pre][j][k][1][1]+cal(j,i));
                    dp[now][j][i][1][1]=min(dp[now][j][i][1][1],dp[pre][j][k][1][1]+cal(k,i));
                    if(i==a){
                        dp[now][i][k][1][0]=min(dp[now][i][k][1][0],dp[pre][j][k][0][0]+cal(j,i));
                        dp[now][i][k][1][1]=min(dp[now][i][k][1][1],dp[pre][j][k][0][1]+cal(j,i));
                    }
                    if(i==b){
                        dp[now][j][i][0][1]=min(dp[now][j][i][0][1],dp[pre][j][k][0][0]+cal(k,i));
                        dp[now][j][i][1][1]=min(dp[now][j][i][1][1],dp[pre][j][k][1][0]+cal(k,i));
                    }
                }
            }
        }
        double ans = 1e15;
        for(int i=0;i<n-1;i++){
            for(int j=0;j<n-1;j++){
                ans=min(ans,dp[now][i][j][1][1]+cal(i,n-1)+cal(j,n-1));
            }
        }
        printf("%.2f
    ",ans);
    }
    

    喵哈哈村的冒菜店

    用线段树来做,首先我们对区间[1..n]开一课线段树。对于每一个节点,维护4个值。分别是l,r,mid,p。l表示在当前结点线段树所在区间,最左边的车停的位置。同理,r表示做右边的车所停的位置。mid表示在这个小区间[l,r]中的紧邻的两辆车的最长距离除以2后的值。p表示取得mid值是所在的紧邻的两辆车的中间位置,也就是在[l,r]中的答案值。

    对于 1 询问:访问线段树的第一个节点,我们比较l-1,n-r,mid的值哪个更大,就选哪个,它们的答案依次是1,n,mid。假设我们求得的位置是car[x]。然后访问[car[x],car[x]]所在的线段树的叶子节点,初始化它的值,然后回溯,进行合并。对于h[x].l与h[x].r可以通过两个儿子的l,r信息得出。对于h[x].mid值,首先在左右儿子的mid值中去一个最大的值。其次考虑一种情况,就是夹在两个线段之间的距离,可以通过(h[x+x+1].l-h[x+x].r) div 2 的值得出在于mid进行比较,然后p就随着mid的值的更新而更新。
    对于2询问:访问询问车所在的位置,直接将它的叶子节点[car[x],car[x]]删除,然后回溯时,再做一次合并操作。即可。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e6+7;
    const int INF = 1e9;
    int car[maxn],sum,n,m;
    struct node{
        int l,r,mid,p;
    }h[maxn];
    void push_up(int x){
        int t;
        if(h[x<<1].l>0)h[x].l=h[x<<1].l;
        else h[x].l=h[x<<1|1].l;
        if(h[x<<1|1].r>0)h[x].r=h[x<<1|1].r;
        else h[x].r=h[x<<1].r;
        h[x].mid=h[x<<1].mid;
        h[x].p=h[x<<1].p;
        if(h[x<<1|1].l>0&&h[x<<1].r>0){
            t=(h[x<<1|1].l-h[x<<1].r)/2;
            if(t>h[x].mid){
                h[x].mid=t;
                h[x].p=(h[x<<1|1].l+h[x<<1].r)/2;
            }
            if(h[x<<1|1].mid>h[x].mid){
                h[x].mid=h[x<<1|1].mid;
                h[x].p=h[x<<1|1].p;
            }
        }
    }
    void work(int x,int l,int r,int num,int kind){
        int mid;
        if(l==r){
            if(kind==2){
                h[x].l=0,h[x].r=0;
                h[x].mid=0,h[x].p=0;
            }else{
                h[x].l=l,h[x].r=r;
                h[x].mid=0,h[x].p=0;
            }
            return;
        }
        mid=(l+r)/2;
        if(num<=mid)work(x<<1,l,mid,num,kind);
        else work(x<<1|1,mid+1,r,num,kind);
        push_up(x);
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            int ch,num;
            scanf("%d%d",&ch,&num);
            if(ch==1){
                if(h[1].l==0)car[num]=1;
                else{
                    sum=-INF;
                    if(h[1].l-1>sum){
                        sum=h[1].l-1;
                        car[num]=1;
                    }
                    if(h[1].mid>sum){
                        sum=h[1].mid;
                        car[num]=h[1].p;
                    }
                    if(n-h[1].r>sum){
                        sum=n-h[1].r;
                        car[num]=n;
                    }
                }
                printf("%d
    ",car[num]);
                work(1,1,n,car[num],1);
            }else{
                work(1,1,n,car[num],2);
            }
        }
    }
    

    喵哈哈村的烧烤店

    相邻的两个做差之后,实际上这个题目就转化为典型的阶梯博弈了。

    http://www.cnblogs.com/mjy0724/p/4465355.html

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    int T,n,a[1001];
    inline int read()
    {
        int x=0;char ch=getchar();
        while(ch<'0'||ch>'9'){ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x;
    }
    int main()
    {
        //freopen("1.in","r",stdin);
        //freopen("1.out","w",stdout);
        T=read();
        while(T--)
        {
            int ans=0;
            n=read();
            for(int i=1;i<=n;i++)
                a[i]=read();
            for(int i=n;i>1;i-=2)
                ans^=(a[i]-a[i-1]);
            if(n&1)ans^=a[1];
            if(ans)printf("Star
    ");
            else printf("Moon
    ");
        }
        return 0;
    }
  • 相关阅读:
    项目管理
    开源视频会议bigbluebutton开发(1)——初始化安装以及配置
    oracle休系统结构
    Tomcat上安装配置Axis
    锁表头
    文件复制三种方法
    程序员技术练级攻略
    Linux (RHEL 5.4)下安装 Oracle 10g R2
    Android 学习资料收集汇总
    WAS61安装调整和应用部署.doc
  • 原文地址:https://www.cnblogs.com/qscqesze/p/6580390.html
Copyright © 2011-2022 走看看