牛客周赛 Round 1题解

题目:游游画U

链接:https://ac.nowcoder.com/acm/contest/60245/A

题目描述:

游游想让你画一个大小为 n 的 "U" ,你能帮帮她吗?
具体的画法见样例说明。

输入描述:

一个正整数n。
1≤n≤50 

 输出描述:

共输出 4n行,每行输出一个长度为 4n 的,仅包含 '*' 和 '.' 两种字符的字符串。

示例 :

输入

复制

3

输出

复制

***......***
***......***
***......***
***......***
***......***
***......***
***......***
***......***
***......***
.***....***.
..***..***..
...******...

解题思路: 

① 这个题目呢,就是纯纯的模拟

②首先我将这个u分为了两个部分,一个部分为前3*n部分(即为固定不变的),另外一个部分为后n部分(有规律的图形)

③接下来就是疯狂的暴力暴力~~~嘻嘻~~友友们,看代码吧~~~

#include
using namespace std;

int main()
{
    int n;
    cin>>n;
    for(int i=0;i<3*n;i++)
    {
        for(int  j=0;j<4*n;j++)
        {
            if(j<=n-1 || j>=4*n-n)
            {
                cout<<"*";
            }
            else
            {
                cout<<".";
            }
        }
        cout<<"\n";
    }
    int t=n;
    int k=1;
    for(int i=0;i

题目:游游的数组染色

链接:https://ac.nowcoder.com/acm/contest/60245/B

题目描述:

游游拿到了一个数组,其中一些数被染成红色,一些数被染成蓝色。
游游想知道,取两个不同颜色的数,且它们的数值相等,有多少种不同的取法?
我们定义,两种取法如果取的某个数在原数组的位置不同,则定义为不同的取法。 

输入描述: 

第一行输入一个正整数 n,代表数组的长度。
第二行输入 n 个正整数 ai​,代表数组中的元素。
第三行输入一个长度为 n ,仅包含 'R' 和 'B' 两种字符的字符串,第 i个字符为 'R' 代表数组第 i个元素被染成红色,为 'B' 代表被染成蓝色。
1≤n≤≤200000
1≤ai​≤109 

输出描述: 

 输出一个整数,代表取数的方案数量。

示例 :

输入

复制

5
1 2 1 2 2
BRRBB

输出

复制

3

说明

第一种取法,取第一个数和第三个数,颜色不同且都是1。

第二种取法,取第二个数和第四个数,颜色不同且都是2。

第三种取法,取第二个数和第五个数,颜色不同且都是2。

解题思路: 

① 这个题目我们可以很容易知道当数值相同的时候,方案个数=一个颜色的个数×另外一个的

②所有我们可以利用结构体来排序,在一个循环中找到数值相同的

③不断记录两个颜色的个数,当数值不同的时候,将方案数算出来,并将计数清零

下面是代码实现~~~

#include
using namespace std;
string s;
struct stu
{
	int zhi;
	char yanse;
}a[200010];
bool cmp(stu x,stu y)
{
	if(x.zhi!=y.zhi) return x.zhiy.zhi;
}
int main()
{
	int n;
	cin>>n;
	for(int i=0;i>a[i].zhi;
	}
	cin>>s;
	for(int i=0;i

 题目:游游的交换字符

链接:https://ac.nowcoder.com/acm/contest/60245/C

题目描述: 

游游拿到了一个01串(仅由字符'0'和字符'1'构成的字符串)。游游每次操作可以交换两个相邻的字符,例如,对于字符串"11001"而言,游游可以交换第二个字符和第三个字符变成"10101"。
游游希望最终字符串任意两个相邻的字符都不相同,她想知道最少需要多少操作次数?保证答案是有解的,即最终一定能形成任意两个相邻的字符都不相同的字符串。

输入描述: 

一行仅由 '0' 、 '1' 组成的字符串,字符串长度 n满足 2≤n≤200000。 

输出描述: 

游游使得相邻两个字母不等的最少操作次数。

示例: 

输入

复制

11100

输出

复制

3

说明

先交换第三个、第四个字符,得到字符串"11010"。
然后交换第二个、第三个字符,得到字符串"10110"。
最后交换第四个、第五个字符,得到字符串"10101"。
总共交换3次。

解题思路: 

① 我们每一次存下当为1或者0的时候的下标,并判断1和0的个数;

②如果1和0的个数不相等,那么就看谁的数量多,就以谁为做交换,然后可以发现下标规律sum+=abs(2*i-ans[i]);,就能得到操作数

③如果0和1的个数相等的话,那么就分别以他们两个算一遍,然后比较谁小就是谁

下面是代码实现~~~

#include
using namespace std;

int main()
{
	string s;
	cin>>s;
	long long sum=0;
	vector ans;
	vector str;
	for(int i=0;istr.size())
	{
		for(int i=0;i

题目:游游的9的倍数 

链接:https://ac.nowcoder.com/acm/contest/60245/D

题目描述: 

游游拿到了一个数字串,她想取一个该数字串的子序列(子序列在原串中可以不连续),使得该子序列是9的倍数。子序列可以包含前导零。
游游想知道,一共能取多少个合法的子序列?答案请对 10^9+7 取模。
我们定义,若两个子序列在原串中的位置不同,则认为它们不同。 

输入描述: 

一个长度不超过200000的,仅由'0'~'9' 十种字符组成的字符串。 

输出描述: 

子序列是9的倍数的数量。答案请对 10^9+7 取模。  

 示例:

输入

复制

1188

输出

复制

5

说明

共可以取4个不同的"18"子序列,和一个"1188"子序列,都是9的倍数。

解题思路: 

① 这个是一道典型的dp题(线性计数的dp)

②主要是记录取余9 的余数当作操作数,其他的就是很正常的dp啦~~

这里还有个类似的dp可以做做:

链接:https://ac.nowcoder.com/acm/problem/21302

#include
using namespace std;
const int N=2e5+10;
char s[N];
int dp[N][10];
const long long mod=1e9+7;
int main()
{
    cin>>s+1;
    int n=strlen(s+1);
    for(int i=1;i<=n;i++)
    {
        int k=(s[i]-'0')%9;
        dp[i][k]+=1;
        dp[i][k]=dp[i][k]%mod;
        for(int j=0;j<9;j++)
        {
            int t=(j-k+9)%9;
            dp[i][j]+=(dp[i-1][j]+dp[i-1][t])%mod;
            dp[i][j]=dp[i][j]%mod;
        }
    }
    cout<

题目:矩阵

链接:https://ac.nowcoder.com/acm/contest/60063/D

题目描述: 

现有一个大小为n×m的二维矩阵,每个元素si,j可能是字符'0'、'1'。
阿宁一开始站在(1,1),目标走到(n,m)。
假设当前在(x,y),一个相邻位置(x′,y′),上下左右 相邻。可以进行以下其中一个行为,花费一个单位时间:
1. 如果sx,y​是'0',sx′,y′​是'1',可以从(x,y)走到(x′,y′)。
2. 如果sx,y​是'1',sx′,y′​是'0',可以从(x,y)走到(x′,y′)。
3. 将sx′,y′′​变成'1'。
4. 将sx′,y′变成'0'。
问阿宁从(1,1)走到(n,m)需要最少多少单位时间? 

输入描述: 

第一行输入两个正整数n,m。
接下来输入n行,每行m个字符,字符仅包含'0'、'1'。
1≤n,m≤10^3 

输出描述: 

输出一个整数。 

示例: 

输入

复制

4 4
1111
1111
1010
0101

输出

复制

7

说明

一开始在(1,1)。将s2,1​变成'0',走到(2,1),走到(3,1),走到(3,2),走到(4,2),走到(4,3),走到(4,4)。

解题思路: 

① 这个是一道BFS算法

②主打一个套y总的模板~~然后再修改~~

//y总模板
//bfs走迷宫
/*
5 5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
 */
#include

using namespace std;

const int N=110; //n,m的数据范围均为100
int g[N][N],d[N][N],n,m; //g[N][N]用来存储迷宫
queue > q; //d[x][y]用来存储(x,y)这一点到坐标原点的距离
//q队列用来存储宽度优先搜素到的路径也就是走迷宫经过哪些点
int bfs()
{
    memset(d,-1,sizeof d); //将d数组所有元素初始化为-1

    d[0][0]=0; //位于原点时到原点的距离为0
    q.push({0,0}); //将原点入队

    int dx[4]={-1,0,1,0},dy[4]={0,-1,0,1}; //定义方向向量一共四个方向

    while(q.size()) //当队列非空时执行循环
    {
        auto t=q.front();
        q.pop(); //插入一个位置的同时会弹出一个位置保证循环可以正常终止

        for(int i=0;i<4;i++) //x,y都要四个方向,遍历四个方向
        {
            int x=t.first+dx[i],y=t.second+dy[i]; //四个方向对应x,y坐标5
            if(x>=0 && x=0 && g[x][y]==0 && d[x][y]==-1 )
            {
                d[x][y]=d[t.first][t.second]+1; //走到下一个点的同时距离加1
                q.push({x,y}); //将该点入队
            }
        }
    }
    return d[n-1][m-1]; //递归回下一个点
}

int main()
{
    scanf("%d%d",&n,&m); //输入迷宫的尺寸大小
    for(int i=0;i
#include 

using namespace std;

const int N = 200003, null = 0x3f3f3f3f;

int h[N];

int find(int x)
{
    int t = (x % N + N) % N;
    while (h[t] != null && h[t] != x)
    {
        t ++ ;
        if (t == N) t = 0;
    }
    return t;
}

int main()
{
    memset(h, 0x3f, sizeof h);

    int n;
    scanf("%d", &n);

    while (n -- )
    {
        char op[2];
        int x;
        scanf("%s%d", op, &x);
        if (*op == 'I') h[find(x)] = x;
        else
        {
            if (h[find(x)] == null) puts("No");
            else puts("Yes");
        }
    }

    return 0;
}

通过题目的代码~: 

#include
using namespace std;
typedef pair PII;
const int N=1010;
int a[N][N]; 
int b[N][N];
int f[N][N];//标志的作用
int n,m;
int bfs()
{
	queue q;//建立队列
	memset(b,-1,sizeof(b));//初始化d数组
	//初始化
	b[0][0]=0;//初始化0,0点
	q.push({0,0});//压入坐标
//坐标:(-1,0) (0,1) (1,0) (0,-1)
	int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
	while(q.size())
{
		auto t=q.front();//取出对头
		q.pop();//插入一个位置的同时会弹出一个位置保证循环可以正常终止
		for(int i=0;i<4;i++)//遍历四个方向
		{
			int x=t.first+dx[i],y=t.second+dy[i];
			int flag=f[t.first][t.second];
			if(x>=0&&x=0&&yb[t.first][t.second]+1)
					{
						b[x][y]=b[t.first][t.second]+1;
						q.push({x,y});
					}
					else if(a[x][y]!=1-flag&&b[x][y]>b[t.first][t.second]+2)
					{
						b[x][y]=b[t.first][t.second]+2;
						q.push({x,y});   
					} 
					
				}
			}
		}
	}
	return b[n-1][m-1];
}
int main()
{
	cin>>n>>m;	
	char x;
	for(int i=0;i>x;
			if(x=='1')
				a[i][j]=1;
			else 
				a[i][j]=0;
		}
	}
	memcpy(f,a,sizeof(a));
	cout<

ok,集训开始啦~~,题解持续更新~~

嘻嘻·~~ 

  

你可能感兴趣的:(题解,算法,c++,数据结构,学习)