• Codeforces补题2020.2.29 (Round623 Div2)


    A.Dead Pixel

    作者有一个a*b大小的矩形,但矩形上有一个点(x,y)是污渍。

    现在需要你计算出避开污渍的情况下切割出的矩形的最大面积。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1014;
    int getArea (int x1,int y1,int x2,int y2,int a,int b) {
        if (x1<0||x1>=a||x2<0||x2>=a||y1<0||y1>=b||y2<0||y2>=b) 
            return 0;
        return (abs(x1-x2)+1)*(abs(y1-y2)+1);
    } 
    int main () {
        int T;
        int a,b,x,y;
        scanf("%d",&T);
        while (T--) {
            scanf("%d%d%d%d",&a,&b,&x,&y);
            int ans=0;
            ans=max(ans,getArea(0,0,x-1,b-1,a,b));
            ans=max(ans,getArea(0,0,a-1,y-1,a,b));
            ans=max(ans,getArea(x+1,0,a-1,b-1,a,b));
            ans=max(ans,getArea(0,y+1,a-1,b-1,a,b));
            printf ("%d
    ",ans);
        }
        return 0;
    }
    View Code

    B.Homecoming

    经过一个长时间的聚会,佩蒂娅决定回家,但事实证明他就在镇的另一端。镇上有n个十字路口,每个十字路口都有公共汽车站或有轨电车站。

    十字路口表示为长度n的字符串s,其中s i=a,如果i-th十字路口有公共汽车站,si=B,如果i-th十字路口有电车站。目前,佩蒂亚在第一个十字路口(对应于s1),他的目标是到达最后一个十字路口(对应于sn)。

    如果两个十字路口i和j,所有十字路口i、i+1、…、j-1都有一个公共汽车站,可以支付一卢布的车票,然后从i-th十字路口乘公共汽车到j-th十字路口(不必在j-th十字路口有一个公共汽车站)。从形式上讲,如果st=a表示i≤t<j,支付一卢布佩特雅可以从i转到j。

    如果i和j两个十字路口i、i+1、…、j-1都有一个有轨电车站,可以支付b卢布的有轨电车车票,然后从i-th十字路口乘有轨电车到j-th十字路口(无需在j-th十字路口有轨电车站)。从形式上讲,如果st=b表示所有i≤t<j,那么支付b卢布Petya可以从i转到j。

    例如,如果s=“AABBBAB”,a=4和b=3,那么Petya需要:

    买一张1到3的巴士票,

    买一张3点到6点的有轨电车票,

    买一张6点到7点的公共汽车票。

    因此,他总共需要花费4+3+4=11卢布。请注意,最后一个十字路口的停车类型(即字符sn)不影响最终费用。

    现在佩蒂亚在第一个十字路口,他想去第n个十字路口。晚会结束后他带着卢布离开了。他决定步行去某个车站,然后只用公共交通工具回家。

    帮他选一个最近的十字路口,我先步行去,这样他就有足够的钱从第一个十字路口到第n个十字路口,只用电车和公共汽车票。

    输入

    每个测试包含一个或多个测试用例。第一行包含测试用例的数量t(1≤t≤104)。

    每个测试用例的第一行由三个整数a、b、p(1≤a、b、p≤105)-公车票成本、电车票成本和Petya拥有的金额组成。

    每个测试用例的第二行由一个字符串s组成,其中s i=A,如果i-th crossroad有公共汽车站,si=B,如果i-th crossroad有电车站(2≤| s |≤105)。

    保证一次测试中所有测试用例的字符串长度之和不超过105。

    输出

    对于每个测试用例,打印一个数字——一个十字路口Petya的最小索引i应该步行。剩下的路(即从i到n他应该使用公共交通工具)。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1014;
    int a,b,p;
    string s;
    int main () {
        int T;
        int a,b,p;
        scanf("%d",&T);
        while (T--) {
            scanf("%d%d%d",&a,&b,&p);
            cin>>s;
            int i;
            for (i=s.length()-2;i>=0;i--) {
                if (s[i]=='A') {
                    if (p<a) break;
                    p-=a;
                }
                if (s[i]=='B') {
                    if (p<b) break;
                    p-=b;
                }
                while (i>0&&s[i]==s[i-1]) i--;
            }
            printf ("%d
    ",i+2);
        }
        return 0;
    }
    View Code

    C.Restoring Permutation

    给你一个序列b1,b2,…,bn。找到字典上最小的排列a1,a2,…,a2n,使得bi=min(a2i-1,a2i),或者确定它是不可能的。

    输入

    每个测试包含一个或多个测试用例。第一行包含测试用例的数量t(1≤t≤100)。

    每个测试用例的第一行由一个整数n-序列b中的元素数(1≤n≤100)组成。

    每个测试用例的第二行包含n个不同的整数b1,…,bn-序列b的元素(1≤bi≤2n)。

    保证所有测试用例的n之和不超过100。

    输出

    对于每个测试用例,如果没有合适的排列,则打印一个数字-1。

    否则,打印2n整数a1,…,a2n-从1到2n的数字的字典最小置换。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1014;
    int N;
    int a[maxn];
    int visit[maxn];
    int h[maxn];
    void solve () {
        memset(h,0,sizeof(h));
        memset(visit,0,sizeof(visit));
        scanf("%d",&N);
        for (int i=0;i<N;i++) {
            scanf("%d",&a[i*2+1]);
            h[a[i*2+1]]=i*2+1;
            visit[a[i*2+1]]=1;
        }
        int now=1;
        for (int i=1;i<=2*N;i++) {
            if (!h[i]) {
                printf ("-1
    ");
                return;
            }
            if (!visit[i]) continue;
            for (int j=i+1;j<=2*N;j++) {
                if (!h[j]) {
                    a[h[i]+1]=j;
                    h[j]=h[i]+1;
                    break;
                }
            }
        }
        for (int i=1;i<=N;i++) {
            for (int j=i+1;j<=N;j++) {
                if (a[i*2]>=a[j*2-1]&&a[j*2]>=a[i*2-1]&&a[j*2]<a[i*2]) {
                    swap(a[i*2],a[j*2]);
                }
            }
        }
        for (int i=1;i<=2*N;i++) 
            printf ("%d ",a[i]);
    }
    int main () {
        int T;
        scanf("%d",&T);
        while (T--) solve();
        return 0;
    }
    View Code

    D.Recommendations

    给出一个序列,只能对序列里的元素进行+1的操作,每个元素+1的代价都不相同。计算使得序列里每个元素互不相同的最小代价。

    include<bits/stdc++.h>
    using namespace std;
    const int maxn=1014;
    typedef long long ll;
    int N;
    int main () {
        scanf("%d",&N);
        vector<pair<int,int>> vi(N);
        for (int i=0;i<N;i++) scanf("%d",&vi[i].first);
        for (int i=0;i<N;i++) scanf("%d",&vi[i].second);
        sort (vi.begin(),vi.end());
        ll ans=0;
        for (int i=0;i<N;) {
            priority_queue<int> q;
            q.push(vi[i].second);
            ll sum=vi[i].second;
            int cur=vi[i].first;
            int j=i+1;
            while (1) {
                while (j<N&&vi[j].first==cur) {
                    q.push(vi[j].second);
                    sum+=vi[j++].second;
                }
                if (q.size()==1) break;
                sum-=q.top();
                ans+=sum;
                q.pop();
                cur++;
            } 
            i=j;
        }
        printf ("%lld
    ",ans);
        return 0;
    }
    View Code

    E.Double Elimination

    辩论赛采取的是双败赛制,下面介绍一下双败赛制(即使您已经知道是怎么回事也请务必读完题面):

    1.参赛队伍从1到2的n次方编号,将进行一对一的比赛。所有的队伍都从胜者组开始。

    2.所有的胜者组比赛将在尚未输掉任何比赛的球队之间进行。球队按队数分组比赛,赢家晋级下一轮胜者组,输家则进入败者组。起初1和2打,3和4打,5和6打,7和8打...,然后1和2打完胜利的 和 3和4打完胜利的再打一场,1和2打完失败的和3和4打完失败的也再打一场,然后,失败组最终胜利的和胜利组最终胜利的再打一场。

    现在,您有一个喜欢的队伍的名单,您可以猜测比赛的输赢。请您计算在所有可能的比赛进程中,有您喜欢的队伍参加的比赛的最大场次。

    为了使您更方便理解,举个例子。一共有4支队伍,编号1,2,3,4。您喜欢的队伍是1和4。第一轮1和2打,3和4打,1,3号队伍胜出,2,4进入败者组,第二轮1和3打,2和4打,3,4胜出,那么最后的决赛就是3和4打,在这个过程中有1、4参加的比赛有5场。

    输入

    第一行输入两个整数N和K,分别代表有N支队伍参加比赛,有K个队伍是你喜欢的。

    第二行输入K个整数,代表K支队伍的编号。

    输出

    输出一个数字,代表有你喜欢的队伍参加的比赛的最大场次。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=((1<<17)+1014);
    int N,K;
    int a[maxn];
    int dp[18][maxn][2][2];
    //dp[i][j][x1][y1]表示从j开始,连续的2^(i)个人比赛,
    //胜利组胜出的人是不是(1/0)你喜欢的队
    //失败组胜出的人是不是(1/0)你喜欢的队
    // dp数组的值表示你喜欢的队伍目前参与了多少场比赛 
    void init () {
        //初始化,把所有的DP值全部初始化为负无穷 
        for (int i=0;i<18;i++) {
            for (int j=0;j<maxn;j++) {
                for (int k=0;k<2;k++) {
                    for (int z=0;z<2;z++) {
                        dp[i][j][k][z]=-1e9;
                    }
                }
            }
        }
    } 
    int main () {
        init ();
        scanf("%d%d",&N,&K);
        for (int i=0;i<K;i++) {
            int x;
            scanf("%d",&x);
            a[x-1]=1;//统一把编号往前挪一位 
        }
        for (int i=1;i<=N;i++) {
            //i从1开始加到N,不断倍增,就是一个从第一轮比赛推到最后一轮决赛的过程 
            for (int j=0;j<(1<<N);j+=(1<<i)) {
                //2^i支队伍为一组,遍历每一组队伍 
                if (i==1) { 
                //如果只有两支队伍,特殊处理,此时只有胜者组 
                    for (int x1=0;x1<2;x1++) {
                        for (int y1=0;y1<2;y1++) {
                            if (x1+y1==a[j]+a[j+1]) 
                                dp[i][j][x1][y1]=((a[j]+a[j+1])>0?1:0);
                            //遍历有比赛情况 
                            //如果两只队伍都是喜欢的队伍,那就一定都会进入下一轮(一个胜者组,一个败者组 
                            //如果两只队伍有一支是喜欢的队伍,那么最多只可能有一支喜欢的队伍进入下一轮(胜者组或败者组)
                            //如果两只队伍都不是喜欢的队伍,那么不会有队伍进入下一轮。
                            //dp最后的值是,如果存在喜欢的队伍,那么不管有一支或两支,它们最多也只能参加一场比赛,所以如式子所示 
                        }
                    }
                }
                else {
                    //有多支队伍,分为胜者组和败者组 
                    for (int x1=0;x1<2;x1++) {
                        for (int y1=0;y1<2;y1++) {
                            for (int x2=0;x2<2;x2++) {
                                for (int y2=0;y2<2;y2++) {
                                    //遍历上一轮两组队伍的所有的比赛情况 
                                    //x1,y1代表胜利组,x2,y2代表失败组 
                                    int cost=dp[i-1][j][x1][y1]+dp[i-1][j+(1<<(i-1))][x2][y2];
                                    //定义当前你喜欢的队伍参与的比赛数量cost是上一轮的两个组分别的dp值之和 
                                    if (x1||x2) cost++;
                                    //如果胜者组至少有一个你喜欢的队伍留下来了,那么你喜欢的队伍会参加当前的比赛,cost值加一
                                    if (y1||y2) cost++;
                                    //如果败者组至少有一个你喜欢的队伍留下了了,那么你喜欢的队伍会参加当前的比赛,cost值加一 
                                    //接下来枚举八种比赛状态 
                                    dp[i][j][x1][x2]=max(dp[i][j][x1][x2],cost+((x2+y1)>0?1:0)); 
                                    dp[i][j][x1][y1]=max(dp[i][j][x1][y1],cost+((x2+y1)>0?1:0));
                                    //上一轮比赛胜出的是x1,y1,那么y1会和x2再比一场,y2直接淘汰 
                                    dp[i][j][x1][x2]=max(dp[i][j][x1][x2],cost+((x2+y2)>0?1:0));
                                    dp[i][j][x1][y2]=max(dp[i][j][x1][y2],cost+((x2+y2)>0?1:0));
                                    //上一轮比赛胜出的是x1,y2,那么y2会和x2再比一场,y1直接淘汰 
                                    dp[i][j][x2][x1]=max(dp[i][j][x2][x1],cost+((x1+y2)>0?1:0));
                                    dp[i][j][x2][y2]=max(dp[i][j][x2][y2],cost+((x1+y2)>0?1:0));
                                    //上一轮比赛胜出的是x2,y2,那么x1会和y2再比一场,y1直接淘汰 
                                    dp[i][j][x2][x1]=max(dp[i][j][x2][x1],cost+((x1+y1)>0?1:0));
                                    dp[i][j][x2][y1]=max(dp[i][j][x2][y1],cost+((x1+y1)>0?1:0));
                                }   //上一轮比赛胜出的是x2,y1,那么x1会和y1再比一场,y2直接淘汰 
                            }
                        }
                    }
                }
            }
        }
        int ans=0;
        for (int i=0;i<2;i++) {
            for (int j=0;j<2;j++) {
                int cost=dp[N][0][i][j];
                //cost表示2^N支队伍遍历完,比赛结束的四种比赛状态 
                if (i+j) cost++;//如果存在喜欢的队伍,就把决赛也算进去 
                ans=max(ans,cost);
            }
        }
        printf ("%d
    ",ans);
        return 0;
    }
    View Code

     

  • 相关阅读:
    linux 配置Apache 、PHP
    SQL Server DML(SELECT)常见用法(二)
    SQL Server DML(UPDATE、INSERT、DELETE)常见用法(一)
    PropertyGrid—添加EventTab
    PropertyGrid—添加属性Tab
    PropertyGrid—默认属性,默认事件,属性默认值
    PropertyGrid—为复杂属性提供下拉式编辑框和弹出式编辑框
    PropertyGrid--为复杂属性提供编辑功能
    PropertyGrid--基本功能
    Intellij IDEA使用(一)项目模板类型
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/12386545.html
Copyright © 2020-2023  润新知