ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Educational Codeforces Round 93 (Rated for Div. 2)题解

2020-08-15 12:31:17  阅读:218  来源: 互联网

标签:Educational Rated int 题解 cin typedef 数组 dp define


A. Bad Triangle

题目:https://codeforces.com/contest/1398/problem/A

题解:一道计算几何题,只要观察数组的第1,2,n个,判断他们能否构成三角形即可。

必须注意:从反方向判断时要注意:两边之和大于第三边的反向是:a[1]+a[2]<=a[n]一定注意为小于等于,两边之差小于第三边的反义是:a[n]-a[2]>=a[1]切记注意是大于等于

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=50010;
ll t,n;
ll a[N];
int main()
{
    ll i,j,k;
    cin>>t;
    while(t--)
    {
        bool flag=true;
        cin>>n;
        for(i=1;i<=n;i++)
            cin>>a[i];
        if(a[1]+a[2]<=a[n]||a[n]-a[2]>=a[1])
            cout<<"1 2 "<<n<<endl;
        else
            cout<<"-1"<<endl;
    }
    return 0;
}

B. Substring Removal Game

题目:https://codeforces.com/contest/1398/problem/B

题解:一到关于字符串的贪心问题,由于我们要1的个数最大,所以只要找相邻的1的个数就好,存到数组后进行排序,由于我们是先手,因此每隔一个取一次。

代码:

#include<bits/stdc++.h>
using namespace std;
int a[110];
bool cmp(int a,int b)
{
    return a>b;
}
int main()
{
    int i,t;
    string s;
    cin>>t;
    while(t--)
    {
        cin>>s;
        int len=s.length();
        int k=0;
        int j=0;
        for(i=0;i<len;i++)
        {
            if(s[i]=='1')
                k++;
            else
            {
                if(k!=0)
                {
                    a[j++]=k;
                    k=0;
                }
            }
        }
        if(k!=0)
            a[j++]=k;
        int ans=0;
        sort(a,a+j,cmp);
        for(i=0;i<j;i++)
        {
            if(i%2==0)
                ans+=a[i];
        }
        cout<<ans<<endl;
    }
    return 0;
}

C. Good Subarrays

题目:https://codeforces.com/contest/1398/problem/C

题解:我认为这道题是最难想的,一开始用暴力,TLE在第三组数据。因而不能用这种方法。

在线处理的方法。

我们想想,用子数组总和减去元素个数,如果是为0,那么就是好子数组,如果好子数组中又包含好子数组呢?那么该好子数组是不是可以分为三个好子数组。

如果不为0呢?那么我们是不是可以记录这个状态,我们继续往后探索的的时候突然发现子数组总和减去元素个数又为我们上次记录过的状态。那么这个子数组是不是可以拆成我们上次记录过的状态子数组和另一个子数组减元素个数为0的好子数组?(仔细思考这里,非常重要!)

那么我们层层深入,如果一个子数组能这样分为我们已经访问过的状态子数组和一个好子数组,那么不就实现在线处理了吗?因为现在我们只要遍历一遍数组了,其他的子数组我们就可以利用当前已经记录的子数组分解获得。那么时间复杂度就大大减小了。

那么我们怎么记录之前状态呢?这里就要使用map容器了,我们标记所有计算的差值状态,利用ans统计值即可。若之前标记过两次,说明我们可以拆成两种情况:一个差值为标记过的子数组和一个好子数组

代码:

#include<bits/stdc++.h>    //POJ不支持
#define rep(i,a,n) for (int i=a;i<=n;i++)//i为循环变量,a为初始值,n为界限值,递增
#define per(i,a,n) for (int i=a;i>=n;i--)//i为循环变量, a为初始值,n为界限值,递减。
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define fi first
#define se second
#define mp make_pair

using namespace std;

const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 1e5;//最大值。
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll>  pll;
typedef pair<int, int> pii;
//*******************************分割线,以上为自定义代码模板***************************************//

int main()
{
    IOS;
    int t,n,i,j;
    string str;
    cin>>t;
    while(t--)
    {
        cin>>n;
        cin>>str;
        ll ans=0,num=0;
        map<int,ll>mp;
        mp[0]=1;//当差值为0时就是一个好数组
        rep(i,0,n-1)
        {
            num+=str[i]-'0';//计算前缀和数组
            ans+=mp[num-(i+1)];//加上当前的状态对应的值
            mp[num-(i+1)]++;//记录上标记一次
            //其实好与坏的区别就在于第一个是好还是坏
        }
        cout<<ans<<endl;
    }
    return 0;
}

D. Colored Rectangles

题目:https://codeforces.com/contest/1398/problem/D

题解:DP题,我们来思考一下他们的状态转移,设我们可以构造的最大矩形数为nnn,(注意:最大矩形数是一定固定的)那么该状态的最优解是不是可以转换为矩形数为n−1n-1n−1的最优解+当前可构建矩形面积的最大值。我们用dp[i][j][k]表示用去了i个R颜色彩棒,j个G个颜色彩棒,k个C颜色彩棒,那么我们表示矩形数为n−1自然对应的彩棒数要减2了,这里注意有三种情况都要判断

需要注意的是必须对其进行排序,因为我们相当于是不断加入三根彩棒,比较当时拥有的彩棒合成矩形最大值,这就是一个矩形的最优解,再往后推,逐渐得到总矩形的最优解

代码:

#include<bits/stdc++.h>    //POJ不支持
#define rep(i,a,n) for (int i=a;i<=n;i++)//i为循环变量,a为初始值,n为界限值,递增
#define per(i,a,n) for (int i=a;i>=n;i--)//i为循环变量, a为初始值,n为界限值,递减。
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define fi first
#define se second
#define mp make_pair

using namespace std;

const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 210;//最大值。
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll>  pll;
typedef pair<int, int> pii;

ll dp[maxn][maxn][maxn];
int r[maxn],g[maxn],b[maxn];
int main()
{
    IOS;
    int R,G,B,i,j,k;
    cin>>R>>G>>B;
    rep(i,0,R-1)
        cin>>r[i];
    rep(i,0,G-1)
        cin>>g[i];
    rep(i,0,B-1)
        cin>>b[i];
    //排序
    sort(r,r+R);
    sort(g,g+G);
    sort(b,b+B);
    rep(i,0,R)
    {
        rep(j,0,G)
        {
            rep(k,0,B)
            {
                if(i&&j)
                    dp[i][j][k]=max(dp[i][j][k],dp[i-1][j-1][k]+r[i-1]*g[j-1]);
                if(i&&k)
                    dp[i][j][k]=max(dp[i][j][k],dp[i-1][j][k-1]+r[i-1]*b[k-1]);
                if(j&&k)
                    dp[i][j][k]=max(dp[i][j][k],dp[i][j-1][k-1]+g[j-1]*b[k-1]);
            }
        }
    }
    cout<<dp[R][G][B]<<endl;
    return 0;
}

 

标签:Educational,Rated,int,题解,cin,typedef,数组,dp,define
来源: https://www.cnblogs.com/xiaofengzai/p/13508277.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有