Acwing第113场周赛(B拼接字符串、C画矩形)

文章讲述了如何处理字符串拼接问题,涉及将非字母字符移除并检查字符串是否能由三个给定字符串拼接而成。此外,还介绍了一种关于在矩形画布上绘制多个不重叠矩形的数学问题,以及两种可能的解题思路。提供了C++代码示例来解决这两个问题。
摘要由CSDN通过智能技术生成

B.拼接字符串(string、或者isalpha函数)

一、题目要求

对于三个由英文字母构成的字符串 A,B,C,如果将它们按某种顺序进行首尾相连拼接,可以得到一个由英文字母构成的字符串 D,那么就称 D 是 A,B,C 的拼接字符串。

在进行上述判断时,忽略英文字母的大小写。

举个例子,假设 A为 a,B 为 b,C为 c,那么以下字符串均为字符串 A,B,C的拼接字符串:abcbcacbaAcbbAcCAB

给定三个字符串 S1,S2,S3,这三个字符串均由大小写英文字母以及三种特殊符号(-; 和 _)构成。

你需要回答 n 个询问。

每个询问给定一个字符串 Q,该字符串也是由大小写英文字母以及三种特殊符号(-; 和 _)构成。

对于每个询问,你需要回答,将字符串 S1,S2,S3, 中的所有非英文字母字符全部去掉后,字符串 Q 是否是字符串 S1,S2,S3的拼接字符串。

输入格式

第 1∼31∼3 行,分别包含字符串 S1,S2,S3。

第 44 行包含一个整数 n。

接下来 n 行,每行包含一个字符串 Q。

输出格式

每个询问输出一行结果,如果将字符串 S1,S2,S3,Q 中的所有非英文字母字符全部去掉后,字符串 Q 是字符串 S1,S2,S3的拼接字符串,则输出 ACC,否则输出 WA

数据范围

前 33 个测试点满足 1≤n≤10
所有测试点满足 1≤n≤1000,1≤|S1|,|S2|,|S3|≤100;1≤|Q|≤600。

输入样例1:
Okqf_
Htkloqf;
V_g;f;r;t;k;y;x;s;
7
VgfrtkyxsHtkloqfOkqf
vgfrtkyxs_HtklOQF_OKQF;;_
VGFRTKYXS___OKQF__HTKLOQF__;;
Okq__Htkloqff__Vgfrtkyxs
Vgfrtk;;yxsHtkloqf___;O;k;q;f;
__________OkqfHtkloqfVgfrtkyxs__________
HtkloqfOkqf_ol_Vgfrtkyxs
输出样例1:
ACC
ACC
ACC
WA
ACC
ACC
WA
输入样例2:
Liqhxk;;
ol___
q_utfoxl
3
Liqhxk__q_ol___utfoXl
ol___liqhxk___q__Utfoxl;
Liqhxk;;ol;;q;;utfo;;xl;;
输出样例2:
WA
ACC
ACC
难度:中等
时/空限制:1s / 256MB
总通过数:591
总尝试数:1137
来源:AcWing,第113场周赛
算法标签

二、思路:

1.先将s1,s2,s3都去掉字符; _  -     然后将三个字符串变成小写或者大写字母

2.q次询问下,查询没个字符是否是由这三个字符串拼接而成,假设都变成小写字母,则有6种情况,abc,acb,bac,bca,cab,cba;

3,建议使用string可以直接相加或者用isalpha函数,C/C++库函数( tolower/toupper)实现字母的大小写转换

ps:

【1】isalpha是一种函数:判断字符ch是否为英文字母,若为英文字母,返回非0(小写字母为2,大写字母为1)。若不是字母,返回0。

【2】tolower(),可以将字符转换成小写,非字母字符不进行处理

【2】toupper(),可以将字符转换成大写,非字母字符不进行处理

三、代码

string

#include<bits/stdc++.h>
#define int long long
using namespace std;
string s1,s2,s3,c;
int t;
void solve()
{
	cin>>c;
	int i,j;
	for(i=0; c[i]!='\0'; i++)
	{
		if(c[i]!='-'&&c[i]!=';'&&c[i]!='_')
		{
			if(c[i]>='A'&&c[i]<='Z')
			{
				s1+=c[i]+32;
			}
			else
			{
				s1+=c[i];
			}
		}
	}
	cin>>c;
	for(i=0; c[i]!='\0'; i++)
	{
		if(c[i]!='_'&&c[i]!=';'&&c[i]!='-')
		{
			if(c[i]>='A'&&c[i]<='Z')
			{
				s2+=c[i]+32;
			}
			else
			{
				s2+=c[i];
			}
		}
	}
	cin>>c;
	for(i=0; c[i]!='\0'; i++)
	{
		if(c[i]!='_'&&c[i]!=';'&&c[i]!='-')
		{
			if(c[i]>='A'&&c[i]<='Z')
			{
				s3+=c[i]+32;
			}
			else
			{
				s3+=c[i];
			}
		}
	}
	cin>>t;
	while(t--)
	{
		string s;
		cin>>c;
		for(i=0; c[i]!='\0'; i++)
		{
			if(c[i]!='_'&&c[i]!=';'&&c[i]!='-')
			{
				if(c[i]>='A'&&c[i]<='Z')
				{
					s+=c[i]+32;
				}
				else
				{
					s+=c[i];
				}
			}
		}
		if(s==s1+s2+s3||s==s1+s3+s2||s==s2+s1+s3||s==s2+s3+s1||s==s3+s2+s1||s==s3+s1+s2)
		{
			cout<<"ACC"<<'\n';
		}
		else
		    cout<<"WA"<<'\n';
	}
}
signed main()
{
	int T=1;
	while(T--)
	{
		solve();
	}
	return 0;
}

isalpha()

#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
string s1,s2,s3,Q,a,b,c;
int q;
string check(string s)
{
	string ans="";
	for(int i=0;i<s.size();i++)
	{
		if(isalpha(s[i]))//是英文字母 
		{
			ans+=tolower(s[i]);// 将其转化为小写字母 
		}
	}
	return ans;
}
void solve()
{
	cin>>s1>>s2>>s3>>q;
	a=check(s1),b=check(s2),c=check(s3);
	while(q--)
	{
		string s;
		cin>>Q;
		s=check(Q);
		if(s==a+b+c||s==a+c+b||s==c+a+b||s==c+b+a||s==b+a+c||s==b+c+a)
		{
			cout<<"ACC"<<'\n';
		} 
		else
		{
			cout<<"WA"<<'\n';
		}
	}
}
signed main()
{
	int T=1;
	while(T--)
	{
		solve();
	}
	return 0;
}

C、画矩形  

一、题目要求

约翰农场中的著名抽象派牛画家贝茜打算画一幅抽象矩形画。

首先,贝茜准备了一张网格纸,并在上面绘制了一个 n×m 的矩形。

接下来,贝茜要连续进行 k 次作画。

每次作画,在上一个绘制的矩形,绘制一个新的矩形。

在绘制矩形时,有以下要求:

  1. 所有矩形的边(包括 n×m 的那个),都是沿着网格线绘制的。
  2. 每一个新矩形都不能与上一个矩形有任何的公共点(即完全位于上一个矩形内)。

请你计算,它一共可能绘制出多少种不同的画作。

由于结果可能很大,你只需要输出对 1e9+7取模后的结果。

例如,如果 n=5,m=6,k=2,那么,贝茜首先在网格纸上绘制一个 5×6 的矩形,如下图:

1.png

随后,贝茜要连续进行 22 次作画(必须不多不少,恰好完成 22 次作画),一共可能绘制出 55 种不同的画作:

2.1.png

 

2.2.png

 

2.3.png

 

2.4.png

 

2.5.png

这里需要注意,虽然在上述 55种画作中,第 1,2种画作之间可以经过翻转或旋转相互转化(第 3,4种画作之间也可以经过翻转或旋转相互转化),但仍视为不同画作。

输入格式

共一行,包含三个整数 n,m,k。

输出格式

一个整数,表示可能绘制出的不同画作的总数量对 1e9+71 取模后的结果。

数据范围

前 33 个测试点满足 1≤n,m≤6。
所有测试点满足 1≤n,m,k≤1000。

输入样例1:
3 3 1
输出样例1:
1
输入样例2:
4 4 1
输出样例2:
9
输入样例3:
5 6 2
输出样例3:
5

 二、思路:


 1、将一个长度为n的线段可以分成n-1条边 (建议)
 //内部画两个矩形 
 从n-1行里面,挑出2*k行 
 从m-1列里面,挑出2*k列;
 总画作的个数=c[n-1][2*k]*c[m-1][2*k];
 
 2、若用dp来做,dp[i][j][k]代表在i*j的画布上可以画k种画(不建议)
 dp[i][j][k]=
Σ​​​​​​​xΣydp[x][y][k-1]
 x的选法i-x-1
 y的选法j-y-1 

三、代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#define int long long
#define endl '\n'
using namespace std;
const int mod=1e9+7;
const int N=1100;
int c[N][N];
int n,m,k;
signed main()
{
	int i,j;
	for(i=0;i<N;i++)//预处理组合数数组 
	{
		for(j=0;j<=i;j++)
		{
			if(!j) c[i][j]=1; 
			else c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
		}
	}
	cin>>n>>m>>k;
	if((2*k>n-1)||(2*k>m-1))
	    cout<<"0"<<'\n';
	else
	    cout<<(c[n-1][2*k]*c[m-1][2*k]%mod)<<endl;
	return 0;
 } 
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值