Educational Codeforces Round 140 (Rated for Div. 2)

文章包含四道编程题目,分别涉及三角形的切割条件判断,基于贪心算法的塔块高度计算,二进制字符串的计数方法,以及比赛胜者预测策略。解题关键在于理解题目要求,运用适当的数据结构和算法来解决问题。
摘要由CSDN通过智能技术生成

A

Cut the Triangle

题意:给定三角形三点坐标,只能从三角形顶点横向或纵向进行切割,问能否切成两个三角形

思路:只要有横坐标或纵坐标在其余两点之间即可

#include <bits/stdc++.h>
#define lowbit(x) x&(-x)
#define ios cin.sync_with_stdio(false)
#define PII pair<int,int>
typedef long long ll;
const int N=1e6+10;
const int inf=0x3f3f3f3f;

using namespace std;
struct node{
    int x,y;
}p[5];
bool cmp(node a,node b)
{
    return a.x<b.x;
}
bool cmp2(node a,node b)
{
    return a.y<b.y;
}
void solve()
{
    cin>>p[1].x>>p[1].y;
    cin>>p[2].x>>p[2].y;
    cin>>p[3].x>>p[3].y;
    sort(p+1,p+3+1,cmp);
    bool f=0;
    if((p[2].x>p[1].x&&p[2].x<p[3].x)) f=1;
    sort(p+1,p+3+1,cmp2);
    if((p[2].y>p[1].y&&p[2].y<p[3].y)) f=1;
    if(f) puts("YES");
    else puts("NO");
}
signed main()
{
    //ios;
    int _t=1;
    cin>>_t;
    while(_t--) solve();
    system("pause");
    return 0;
}

B

 Block Towers

 题意:有n座塔,每座塔有a[i]件物品。当a[i]>a[j]时,每次可以从i号塔拿一件物品到j号塔。问1号塔的最大高度。

思路:直接贪心先将第2~n座楼塔按照高度进行从小到大排序,然后从第二个楼塔开始,依次往第一座楼塔上增加高度,直至操作完所有的楼塔即可

#include <bits/stdc++.h>
#define lowbit(x) x&(-x)
#define ios cin.sync_with_stdio(false)
#define PII pair<int,int>
#define int long long
typedef long long ll;
const int N=1e6+10;
const int inf=0x3f3f3f3f;

using namespace std;
int n;
int a[N];
void solve()
{
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    int now=a[1];
    sort(a+2,a+n+1);
    for(int i=2;i<=n;i++)
    {
        if(a[i]>now)
        {
            int ave=(now+a[i]+1)/2;
            now=ave;
        }
    }
    cout<<now<<'\n';
}
signed main()
{
    //ios;
    int _t=1;
    cin>>_t;
    while(_t--) solve();
    system("pause");
    return 0;
}

C

Count Binary Strings

题意: 问构造长度为n的01串的方案数,给出数组a[i][j]表示从第i个位置到第j个位置的限制。

若a[i][j]=1,表示从第i个位置到第j个位置字符都相同

若a[i][j]=2,表示从第i个位置到第j个位置存在不同字符

若a[i][j]=0,表示从第i个位置到第j个位置不做限制

思路:注意到a[1][r],a[2][r]....a[r][r]一定是2 2 ....2 1 1...1的形式。

设f[i][j]表示a[1~i-1] [j]等于2,a[i~j][j]等于1的合法方案数。答案即为Σa[i][n]

初始化f[1][1]=2,表示有0 1两种方案。遍历r和l,更新f[l][r]:先判断a[1~l-1][r]是否全为2或0,a[l~r][r]是否全为1,不能同时满足这两个条件的f[l][r]=0.接下来分情况讨论,当第r个字符与第r+1个字符相同时,f[l][r+1]=f[l][r+1]+f[l][r];当第r个字符与第r+1个字符不同时,f[r+1][r+1]=f[r+1][r+1]+f[l][r].

#include <bits/stdc++.h>
#define lowbit(x) x&(-x)
#define ios cin.sync_with_stdio(false)
#define PII pair<int,int>
typedef long long ll;
const int N=110;
const int inf=0x3f3f3f3f;
const int mod=998244353;
using namespace std;
int n;
int a[N][N];
int f[N][N];
void solve()
{
    cin>>n;
    for(int i=1;i<=n;i++)
        for(int j=i;j<=n;j++)
            cin>>a[i][j];
    
    f[1][1]=2;
    for(int r=1;r<=n;r++)
        for(int l=1;l<=r;l++)
        {
            bool flag=1;
            for(int i=1;i<l;i++)
                if(a[i][r]==1) flag=0;
            for(int i=l;i<=r;i++)
                if(a[i][r]==2) flag=0;
            if(!flag) f[l][r]=0;
            f[l][r+1]=(f[l][r+1]+f[l][r])%mod;
            f[r+1][r+1]=(f[r+1][r+1]+f[l][r])%mod;
        }

    int ans=0;
    for(int i=1;i<=n;i++)
        ans=(ans+f[i][n])%mod;
    cout<<ans<<'\n';
}
signed main()
{
    //ios;
    int _t=1;
    //cin>>_t;
    while(_t--) solve();
    system("pause");
    return 0;
}

D

Playoff

题意:有2^n只队伍,所有队伍的能力是1~2^n的排列。每阶段每两只队伍间进行比赛,直至剩余一只获胜队伍。给定字符串s,s[i]=0表示第i阶段能力低的获胜;s[i]=1表示第i阶段能力高的队伍获胜。 问给定s的情况下,哪些队伍可以最终获胜。

思路:注意到获胜队伍一定是连续的区间。假设有cnt轮高能力获胜比赛,那么在第cnt轮高能力比赛中,若x获胜,则会有一个能力低者;为使这两名选手晋级,第cnt-1轮高能力比赛中会有4名能力比x低...低能力比赛同理

#include <bits/stdc++.h>
#define lowbit(x) x&(-x)
#define ios cin.sync_with_stdio(false)
#define PII pair<int,int>
typedef long long ll;
const int N=1e6+10;
const int inf=0x3f3f3f3f;

using namespace std;
int n;
string s;
void solve()
{
    cin>>n;
    cin>>s;
    int cnt0=0,cnt1=0;
    for(int i=0;i<s.length();i++)
    {
        if(s[i]=='0') cnt0++;
        else cnt1++;
    }
    int l=1<<cnt1;
    int r=(1<<n)+1-(1<<cnt0);
    for(int i=l;i<=r;i++)
        cout<<i<<' ';
    cout<<'\n';
}
signed main()
{
    //ios;
    int _t=1;
    // cin>>_t;
    while(_t--) solve();
    system("pause");
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值