Codeforces Round #632 (Div. 2) Apr/08/2020 22:35UTC+8

比赛链接 https://codeforces.com/contest/1333
比赛记录 https://blog.csdn.net/cheng__yu_/article/details/105395197

A. Little Artem(水)

在这里插入图片描述
题意:用W和B给矩阵涂色,要求黑白相邻的点:B=W+1

#include <bits/stdc++.h>
#define ll long long 
using namespace std;
const int maxn=2e5+10;

int t;
int n,m;

int main()
{
	cin>>t;
	while(t--)
	{
		cin>>n>>m;
		for(int i=1;i<=n;++i)
		{
			for(int j=1;j<=m;++j)
				if(i==1&&j==1)
					printf("W");
				else
					printf("B");
			puts(""); 			
		}
	}	
	return 0;
}

B. Kind Anton

在这里插入图片描述

题意:a数组由{-1,0,1}组成。可以对a数组做无限次 a j = a i + a j a_j=a_i+a_j aj=ai+aj 的操作,问最后能否变成 b 数组
思路

  • b [ i ] > a [ i ] b[i]>a[i] b[i]>a[i],只要 i 的前面有 1 1 1 就可以
  • b [ i ] < a [ i ] b[i]<a[i] b[i]<a[i],只要 i 的前面有 − 1 -1 1 就可以
#include <bits/stdc++.h>
#define ll long long 
using namespace std;
const int maxn=1e5+10;
int t,n;
bool v1[maxn],v2[maxn];
int a[maxn],b[maxn];

int main()
{
	scanf("%d",&t);
	while(t--)
	{
		memset(v1,false,sizeof(v1));
		memset(v2,false,sizeof(v2));	
		scanf("%d",&n);
		bool flag1=false,flag2=false;
		for(int i=1;i<=n;++i)
		{
			scanf("%d",&a[i]);
			if(flag1)	v1[i]=true;
			if(flag2)	v2[i]=true;
			if(a[i]==1)	flag1=true;
			if(a[i]==-1)flag2=true;
		}
		for(int i=1;i<=n;++i)
			scanf("%d",&b[i]);	
		if(b[1]!=a[1])
		{
			puts("NO");
			continue;
		}
		
		bool valid=true;
		for(int i=n;i>=2;--i)
		{
			if(b[i]==a[i])
				continue;
			if(b[i]>a[i])
			{
				if(!v1[i])
				{
					valid=false;
					break;
				}
			}
			
			if(b[i]<a[i])
			{
				if(!v2[i])
				{
					valid=false;
					break;
				}
			}
		}	
		if(valid)
			puts("YES");
		else
			puts("NO");
	}
	return 0;
}

C. Eugene and an array(前缀和零集)

在这里插入图片描述
题意:一个数组没有 0 集(某一段连续相加为0)则认为是好数组。给定一个数组求子数组是好数组的数量
思路:每一个点往左找能够到达的最远的点,即不超过 0 集

#include <bits/stdc++.h>
#define ll long long 
using namespace std;
const int maxn=2e5+10;
int n,x;
map<ll,int> m;

int main()
{
	scanf("%d",&n);
	ll pref=0,ans=0;
	int l=0;
	m[0]=0;
	for(int i=1;i<=n;++i)
	{
		scanf("%d",&x);
		pref+=x;
		if(m.count(pref))
			l=max(l,m[pref]+1);
		ans+=i-l;
		m[pref]=i;
	}	
	printf("%lld\n",ans);
	return 0;
}

D. Challenges in school №41(模拟)

在这里插入图片描述
思路:预处理同时转向,然后拆成 k 次输出

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e5+10;
int n,k;
string s;
vector<int> vec[maxn];

int main()
{
    cin>>n>>k>>s;
    s="0"+s;
    int cnt=0;
    int sum=0;
    while(1)
    {
        bool ok=false;
        cnt++;
        for(int i=1;i<n;++i)
        {
            if(s[i]=='R'&&s[i+1]=='L')
            {
                vec[cnt].push_back(i);
                swap(s[i],s[i+1]);
                i++;
                ok=true;
            }
        }
        if(!ok)
            break;
        sum+=vec[cnt].size();
    }
    cnt--;
    if(k<cnt||k>sum)
    {
        puts("-1");
        return 0;
    }

    for(int i=1;i<=cnt;++i)
    {
        while(!vec[i].empty()&&k>cnt-i+1)
        {
            puts("1");
            cout<<vec[i].back()<<"\n";
            vec[i].pop_back();
            k--;
        }
        if(!vec[i].empty())
        {
            cout<<vec[i].size()<<" ";
            for(auto j : vec[i])
                cout<<j<<" ";
            puts("");
            k--;
        }
    }
    return 0;
}

E. Road to 1600(构造)

在这里插入图片描述
题意:构造一个 n × n n \times n n×n 的矩阵,使得骑士的花费比皇后的少
思路:构造一个 3 × 3 3 \times 3 3×3 的矩阵,利用皇后的性质,让它斜着走到某个角落,从而多出花费

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=500+10;

int n;
int a[maxn][maxn];

int main()
{
    cin>>n;
    if(n==1||n==2)
    {
        puts("-1");
        return 0;
    }
    int cnt=0;
    for(int i=n;i>=4;--i)
    {
        if(i&1)
        {
            for(int j=1;j<=i;++j)
                a[j][i]=++cnt;
            for(int j=i-1;j>=1;--j)
                a[i][j]=++cnt;
        }
        else
        {
            for(int j=1;j<=i;++j)
                a[i][j]=++cnt;
            for(int j=i-1;j>=1;--j)
                a[j][i]=++cnt;
        }
    }
    int x=n*n-9;
    a[1][1]=4,a[1][2]=3,a[1][3]=1;
    a[2][1]=5,a[2][2]=2,a[2][3]=8;
    a[3][1]=9,a[3][2]=6,a[3][3]=7;
    for(int i=1;i<=3;++i)
        for(int j=1;j<=3;++j)
            a[i][j]+=x;

    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
            printf("%d%c",a[i][j],j==n?'\n':' ');
    return 0;
}

F. Kate and imperfection(思维)

在这里插入图片描述
题意:给定集合S: { 1 , 2 , … , n } \{1,2,\dots ,n \} {1,2,,n}找所有 k 子集中,最大gcd(a,b)最小的子集,定义这个最大gcd(a,b)为 I i I_i Ii,输出 I 2 I_2 I2 I n I_n In
思路:假设构造一个 这样的子集,那就是先把 1和质数都丢到集合里面去,然后是2的倍数,3的倍数,4的倍数,5的倍数。如果 x 的 gcd 最后被 a 更新,x 加入集合后的gcd就是 a

#include <bits/stdc++.h>
#define ll long long 
using namespace std;
const int maxn=2e5+10;

int n;
int main()
{
	scanf("%d",&n); 
	vector<int> ans(n + 1, 1); 
	for(int i=2;i<=n;++i)
		for(int j=2*i;j<=n;j+=i)
			ans[j]=i;
	sort(ans.begin(), ans.end());
	for(int i=2;i<=n;++i)
		printf("%d%c",ans[i],i==n?'\n':' ');
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值