Codeforces Round #745 (Div. 2)(A-C)

目录

A. CQXYM Count Permutations

B. Diameter of Graph

C. Portal


A. CQXYM Count Permutations

Problem - A - CodeforcesCodeforces. Programming competitions and contests, programming communityhttps://codeforces.com/contest/1581/problem/A题意:给你一个n然后求有几个2n的全排列是满足条件的,条件:一个排列数组中的p(i)< p(i + 1)中的i的数量是大于n的。

思路:已知有2n个元素,那么一共有(2*n)!种排列方式,这些排列方式都是对称的,对于所以符合题目要求的大于n的和小于等于n的根据对称性应该是数量一样的,那我们就除一个2就可以了:

即为(2*n)!/2.因为要取模,不能直接做除法,我们可以化简,就变成了从3一直乘到2n

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N =5e5+10,mod=1000000007;
void solve()
{
    int n,ans=1;
    cin>>n;
    n*=2;
    for(int i=n;i>=3;i--)
    {
        ans=ans*i%mod;
    }
    cout<<ans<<"\n";
}
signed main()
{
    int t;
    cin>>t;
    while(t--)
       solve();
    return 0;
}

B. Diameter of Graph

Problem - B - CodeforcesCodeforces. Programming competitions and contests, programming communityhttps://codeforces.com/contest/1581/problem/B题意:给你n,m,k,n个点,m条边,要求n个点用m条边任意苏荷相连,问任意两边的最大距离严格小于k-1的情况是否存在.

思路:我们只需要确定输出YES的情况即可.我们要组成图,一定要有m>=n-1条边.最大的情况就是,每两个点之间互相连线(但是因为不能重复,所以用n*(n-1)之后还要除2),当m==n*(n-1)/2的时候任意两点的最长长度都是1.求出k的范围是否合法即可.当m在[ n-1 , n*(n-1)/2 )这个区间时,可以至少组成一个每两点之间距离最大是2的图:

 在这个范围最大值始终为2,判断k的值即可.

当然还有n=1的时候进行1特判.

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N =5e5+10,mod=998244353;
void solve()
{
    int n ,m ,k;
    cin>>n>>m>>k;
    if(n==1&&m==0&&k>=2)
    { 
        cout<<"YES\n";
        return ;
    }
    if(n-1<=m&&m<(n-1)*(1+n-1)/2&&k>=4)
    {
        cout<<"YES\n";
        return ;
    }
    if((n-1)*(1+n-1)/2==m&&k>=3)
    {
        cout<<"YES\n";
        return ;
    }
    cout<<"NO\n";
    return;
}
signed main()
{
    int t;
    cin>>t;
    while(t--)
       solve();
    return 0;
}

C. Portal

Problem - C - CodeforcesCodeforces. Programming competitions and contests, programming communityhttps://codeforces.com/contest/1581/problem/C题意:给你一个01矩阵(1为黑曜石砖,0为空气),在最小的01转换操作下(每一次把0变成1,把1变成0)存在一个高a>=5,宽b>=4的末地传送门(四条边都是黑曜石砖(即为1),四个角无所谓,可以为0也可以为1).问最小操作数.

思路:直接进行二维前缀和,看中间区域和边区域需要转换的个数,枚举端点,巨鹿需要转换的最小个数即可.但是n^4肯定会t,所以我们进行一个剪枝qwq;剪枝操作我在代码里写注释.

#include<bits/stdc++.h>
using namespace std;
char ma[504][504];
int sum[504][504];
int query(int cx, int cy, int zx, int zy)
{
    return sum[zx][zy]-sum[cx-1][zy]-sum[zx][cy-1]+sum[cx-1][cy-1];
}
void solve()
{
    int n,m,ans=1e9;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        scanf("%s",ma[i]+1);
    memset(sum,0,sizeof sum);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+(ma[i][j]-'0');
    for(int i=1;i+4<=n;i++)
    {
        for(int j=1;j+3<=m;j++)
        {
            for(int k=i+4;k<=n;k++)
            {
                for(int l=j+3;l<=m;l++)
                {
                    int zhongjian=query(i+1,j+1,k-1,l-1);
                    int h1=k-i-1-query(i+1,j,k-1,j);
                    int h2=l-j-1-query(i,j+1,i,l-1);
                    int l1=k-i-1-query(i+1,l,k-1,l);
                    int l2=l-j-1-query(k,j+1,k,l-1);
                    int tt=h1+h2+l1+l2+zhongjian;
                    if(tt-l1>ans)
                        break;
//我们已经确定了三条边了,现在在枚举第四条边,当我不算第四条边的时候,
已经大于我所记录的最小值,那么再加上枚举的第四条边,肯定也是大于记录的
最小值,所以继续枚举无意义,直接break;
                    ans=min(ans,tt);   
                }
            }
        }
    }
    cout<<ans<<"\n";
    return ;
}
signed main()
{
    int t;
    cin>>t;
    while(t--)
       solve();
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值