2.5总结

 P1229 遍历问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

分析:

首先我们要找到它的子节点只有一个的这种节点,假设有n个,而中序遍历的种数就是2的n次。

代码:

#include <stdio.h>
#include <string.h>
int main()
{
    char q[1000],h[1000];
    int s=1;
    scanf("%s%s",q,h);
    for(int i=0;i<strlen(q);i++)
    {
        for(int j=0;j<strlen(h);j++)
        {
            if(q[i]==h[j]&&q[i+1]==h[j-1]&&i+1<strlen(q)&&j-1>=0)
            s*=2;
        }
    }
    printf("%d\n",s);
    return 0;
}

 


P3367 【模板】并查集 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

分析:

  • 知道并查集的模板;
  • 当 Zi​=1 时,将 Xi​ 与 Yi​ 所在的集合合并。
  • 当 Zi​=2 时,输出 Xi​ 与 Yi​ 是否在同一集合内,是的输出 Y ;否则输出 N 。

代码:

#include <stdio.h>
int a[10001],m,n;
int geta(int b)
{
    if(a[b]==b)
    return b;
    else
    {
        a[b]=geta(a[b]);
        return a[b];
    }
}
int main()
{
    int x,y,z;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    a[i]=i;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&z,&x,&y);
        if(z==1)
        a[geta(x)]=geta(y);
        else
        {
            if(geta(x)==geta(y))
                printf("Y\n");
            else
                printf("N\n");
        }
    }
    return 0;
}

 


 

P2078 朋友 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

分析:

  • 并查集的模板题 
  • 使用并查集分别找出小明和小红的盆友各有多少(包括自己),朋友少的也就是可以组成情侣的数量

代码:

#include <stdio.h>
int a[100000],b[100000],m,n,q,p,c=0,d=0;
int geta(int r)
{
    if(a[r]==r)
    return r;
    else
    {
        a[r]=geta(a[r]);
        return a[r];
    }
}
int getb(int r)
{
    if(b[r]==r)
    return r;
    else
    {
        b[r]=getb(b[r]);
        return b[r];
    }
}
int main()
{
    int x,y,z;
    scanf("%d%d%d%d",&n,&m,&p,&q);
    for(int i=1;i<=n;i++)
    a[i]=i;
    for(int i=1;i<=m;i++)
    b[i]=i;
    for(int i=1;i<=p;i++)
    {
        scanf("%d%d",&x,&y);
        a[geta(x)]=geta(y);
    }
    for(int i=1;i<=q;i++)
    {
        scanf("%d%d",&x,&y);
        x*=-1;y*=-1;
        b[getb(x)]=getb(y);
    }
    for(int i=1;i<=n;i++) 
    {
        if(geta(i)==geta(1))
        c++;
    }

    for(int i=1;i<=m;i++) 
    {
        if(getb(i)==getb(1))
        d++;
    }
    if(c>d)
    printf("%d\n",d);
    else
    printf("%d\n",c);
    return 0;
}

 


 

P1036 [NOIP2002 普及组] 选数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

分析:

  • sushu(int b) 函数用于判断一个整数是否为素数,如果是素数则返回 1,否则返回 0。
  • dfs(int m, int s, int j) 函数是递归函数,用于进行深度优先搜索。其中参数 m 表示当前已经选择了几个数字,s 表示当前已经选择的数字的和,j 表示当前可以选择的数字的起始位置。
  • dfs 函数中,如果已经选择了 k 个数字,则判断它们的和是否为素数,如果是素数,则将方案数 t 加一。
  • 否则,继续从当前位置开始选择数字,然后递归调用 dfs 函数。
  • main() 函数中,首先读入数组的大小 n 和要选择的数字个数 k,然后读入数组元素。
  • 调用 dfs(0, 0, 0) 开始深度优先搜索,并输出方案数 t。

代码:

#include<stdio.h>
int n,k,a[25],t;
int sushu(int b)
{
	int i;
	if(b<2)
		return 0;
	for(i=2;i*i<=b;i++)
		if(b%i==0)
			return 0;
	return 1;
}
void dfs(int m,int s,int j)
{
	int i;
	if(m==k)
    {
		if(sushu(s))
		t++;
		return;
	}
	for(i=j;i<n;i++)
	dfs(m+1,s+a[i],i+1);
	return;
}
int main()
{
	int i;
	scanf("%d %d",&n,&k);
	for(i=0;i<n;i++)
    {
		scanf("%d",&a[i]);
	}
	dfs(0,0,0);
	printf("%d\n",t);
	return 0;
}

 


D - LOWER 

题目描述

给定一个长度为 N 的字符串 S,由大写和小写英文字母组成。

让我们对字符串 S 执行 Q 次操作。 第 i 次操作 (1≤i≤Q) 由一个包含两个整数和一个字符的元组 (ti​,xi​,ci​) 表示,具体如下。

  • 如果 ti​=1,将 S 的第 xi​ 个字符改为 ci​。
  • 如果 ti​=2,将 S 中所有大写字母转换为小写(不要使用 xi​,ci​ 进行此操作)。
  • 如果 ti​=3,将 S 中所有小写字母转换为大写(不要使用 xi​,ci​ 进行此操作)。

在执行完 Q 次操作后,输出 S。

约束条件

  • 1≤N≤5×105
  • S 是一个长度为 N 的字符串,由大写和小写英文字母组成。
  • 1≤Q≤5×105
  • 1≤ti​≤3 (1≤i≤Q)
  • 如果 ti​=1,那么 1≤xi​≤N (1≤i≤Q)。
  • ci​ 是一个大写字母或小写字母。
  • 如果 ti​=1,那么 xi​=0 并且 ci​= 'a'
  • N,Q,ti​,xi​ 都是整数。

输入

输入以以下格式从标准输入给出:

N
S
Q
t1​ x1​ c1​
t2​ x2​ c2​
⋮⋮
tQ​ xQ​ cQ​

输出

在一行中输出答案。

示例 1

InputcopyOutputcopy
7
AtCoder
5
1 4 i
3 0 a
1 5 b
2 0 a
1 4 Y
atcYber

初始时,字符串 S 为 AtCoder

  • 第一次操作将第 4 个字符改为 i,将 S 变为 AtCider
  • 第二次操作将所有小写字母转换为大写,将 S 变为 ATCIDER
  • 第三次操作将第 5 个字符改为 b,将 S 变为 ATCIbER
  • 第四次操作将所有大写字母转换为小写,将 S 变为 atciber
  • 第五次操作将第 4 个字符改为 Y,将 S 变为 atcYber

执行完操作后,字符串 S 变为 atcYber,因此输出 atcYber

分析:

  • 第一次看到道题目想到的是边输入边进行判断,而将字符串全变为大写或小写,就得将字符串重新遍历,如果字符长度过长或变得次数过多,就会时间超限
  • 看一下题发现这题的内存限制还是比较大的,所以我们先可以将输入都存放在数组里面,但不要开二维数组
  • 简单思考一下,可以发现其实我们只要知道最后一次改大小写的地方就行了,前面怎么变不用管

代码:

#include <stdio.h>
int n,t,r;
    char s[500001];
    int q,a[500001],b[500001];
    char c[500001];
int main()
{
    scanf("%d",&n);
    scanf("%s",s);
    scanf("%d",&q);
    for(int i=0;i<q;i++)
    {
        scanf("%d%d %c",&a[i],&b[i],&c[i]);
        if(a[i]==2)
        t=i;    
        else if(a[i]==3)
        t=i; 
    }
    for(int i=0;i<q;i++)
    {
        if(i==t)
        {
            if(a[i]==2)
        {
            for(int i=0;i<n;i++)
            {
                if(s[i]>='A'&&s[i]<='Z')
                s[i]+=32;
            }
        }
        else if(a[i]==3)
        {
            for(int i=0;i<n;i++)
            {
                if(s[i]>='a'&&s[i]<='z')
                s[i]-=32;
            }
        }
        }
        if(a[i]==1)
        {
            s[b[i]-1]=c[i];
        }

    }
       
    printf("%s\n",s);
    return 0;
}

 


P1135 奇怪的电梯 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

分析:

dfs,处理好边界就行了

代码:

#include <stdio.h>
int n,a,b,k[201],ans[201];
void dfs(int x,int z)
{
    ans[x]=z;
	if(x+k[x]<=n&&z+1<ans[x+k[x]])
	dfs(x+k[x],z+1);
	if(x-k[x]>0&&z+1<ans[x-k[x]])
	dfs(x-k[x],z+1);
}
int main()
{
    for(int i=1;i<=201;i++)
    {
        ans[i]=999999;
    }
    scanf("%d%d%d",&n,&a,&b);
    for(int i=1;i<=n;i++)
    scanf("%d",&k[i]);
    dfs(a,0);
    if(ans[b]==999999)
    printf("-1\n");
    else
    printf("%d\n",ans[b]);
    return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值