蓝桥杯python组国赛复盘

却道一句当时只道是寻常

python国赛复盘

我是个c++选手,python就国赛前学了半个下午加晚上,省赛前学了半天。所以填空题部分还是选择了,用c++编程,机房提供了DEV还是很不错的
写题顺序大概是:A,B,C,D,E,F,H,I,j,G。两个多小时的时候已经写完了除了D题和G题的其他题目,然后之后就是在debug,调试python代码了(调试python的remove和pop函数,心得见G题)。对python语法的不熟练应该是比赛的最大的障碍了,临时摸鱼抱佛脚还是不太靠谱的。
蓝桥杯python组国赛复盘_第1张图片

print(200/8)
# 答案是25

蓝桥杯python组国赛复盘_第2张图片

#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
int a[] = {2,3,5,7};
bool check(int x)
{
    for(int i=2;i*i<=x;i++)
        if(x%i==0)
            return false;
    while(x)
    {
        int t=x%10;
        x/=10;
        int flag = 0;
        for(int i=0;i<4;i++)
            if(a[i]==t)
            {
                flag=1;
                break;
            }
        if(flag==0) return false;
    }
    return true;
}
int main()
{
    int cnt=0;
    for(int i=2;i<=20210605;i++)
        if(check(i)) cnt++;
    cout<<cnt<<endl;
    return 0;
}

答案为1903

蓝桥杯python组国赛复盘_第3张图片

#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
int month[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int check(int x)
{
	int res=0;
	while(x)
	{
		res=res+x%10;
		x/=10;
	}
	return res;
}
int main()
{
	int cnt=0;
	for(int i=2001;i<=2021;i++)
	{
		if((i%4==0 && i%100!=0) || i%400==0)
			month[2]=29;
		else
			month[2]=28;
		for(int j=1;j<=12;j++)
		{
			for(int k=1;k<=month[j];k++)
			{
				int tmp=check(i)+check(j)+check(k);
				int a=sqrt(tmp);
				if(a*a==tmp)
					cnt++;
			}
		}
	}
	cout<<cnt<<endl;
    return 0;
}

答案为977

蓝桥杯python组国赛复盘_第4张图片
(这题乱想了好多假算法)我一开始看错题了,以为是最大权值,算了个答案长度为600多的数字。后面回过头来一想一道10分的填空题用C++写岂不是还要写个高精度,应该不会这么复杂。后面转身一读题,是最小权值,又继承了上面最大权值的假算法接着想了个假算法(类似于一颗哈夫曼树,右边子树高度为1010,左子树每个子树配一个叶子,额,假算法、好坑啊!!!),以上显然错误,这样只可能找出最大的权值。。。后面一想,这个应该是一条链,只带左子树的链或者是一个完全二叉树,时间不够了。赛后发现这题正解应该是dp

蓝桥杯python组国赛复盘_第5张图片
两行代码就解决了,当时有点懵,不过的确就是这么简单,额

s = input()
print(s.upper())

蓝桥杯python组国赛复盘_第6张图片
蓝桥杯python组国赛复盘_第7张图片
数据范围挺大的所以要以o(n)的复杂度,或者是o(nlogn)跑出来就行,我写了个o(nlogn)的复杂度满足即可

import bisect
import math
N = int(math.sqrt(2*1e12))+5000
f = [i*(i+1)//2 for i in range(N)]
s = [0 for i in range(N)]
for i in range(1,N):
    s[i]=s[i-1]+f[i]
def get(x):
    if x<1:
        return 0
    p = bisect.bisect_right(f,x,1,N)
    p = p-1
    if f[p]==x:
        return s[p]
    else:
        a = x-f[p]
        a = a*(a+1)//2
        return s[p]+a

t = int(input())
for i in range(t):
    l,r = list(map(int,input().split()))
    print(get(r)-get(l-1))

蓝桥杯python组国赛复盘_第8张图片
蓝桥杯python组国赛复盘_第9张图片
数据范围不大,c++用set重载一下,或者map应该就可以过了,大致思路就是模拟,用hash维持一个各个体积的冰山出现的次数和,然后每次询问更新这个维护的容器即可。可惜我用的是python,对map操作不是很熟练,写了个大模拟。。。

记录坑点:这道题比较要注意坑的地方就是,用python的pop或者是remove函数,如果用for循环pop掉或者remove掉之后,之后元素的序号会替换掉之前的元素序号,而遍历仍然在进行,所以遍历的时候会出现报错。我的解决办法是将要remove掉的下标放一个数组里头,然后重点是:放数组里头后remove/pop操作要从后往前remove/pop这样就可以保持修改后的下标不会对之前造成影响。

n,m,k = list(map(int,input().split()))
a = list(map(int,input().split()))
b = []
c = []
mod = 998244353
ans = sum(a)%mod
def calc():
    res = 0
    res = sum(a)
    for i in range(len(b)):
        res = res+b[i]*c[i]
    res = res%mod
    return res

def check(x,y):
    q = []
    lb = len(b)
    for i in range(lb):
        if b[i]+x<=0:
            q.append(i)
        elif b[i]+x>k:
            b.append(1)
            c.append((b[i]+x-k)*c[i])
            b[i] = k
        else:
            b[i]=b[i]+x
    for i in range(len(q)-1,-1,-1):
        b.pop(q[i])
        c.pop(q[i])
    q = []
    for i in range(len(a)):
        if a[i]+x<=0:
            q.append(i)
        elif a[i]+x>k:
            b.append(1)
            c.append(a[i]+x-k)
            a[i] = k
        else:
            a[i] = a[i]+x
    for i in range(len(q)-1,-1,-1):
        a.pop(q[i])
    a.append(y)

for i in range(m):
    x,y = list(map(int,input().split()))
    check(x,y)
    ans = calc()
    print(ans)

蓝桥杯python组国赛复盘_第10张图片
考场上为了追求速度写了个大暴力,用前缀和和前缀积维护答案,然后两重for循环超级大暴力,应该可以拿50%的分,正解应该是找到数的某种性质

n = int(input())
N = 200010
a = list(map(int,input().split()))
b = [0 for i in range(N)]
s = [1 for i in range(N)]
for i in range(1,n+1):
    b[i] = b[i-1]+a[i-1]
    s[i] = s[i-1]*a[i-1]
ans = 0
for i in range(1,n+1):
    for j in range(i+1,n+1):
        if s[j]==s[i-1]*(b[j]-b[i-1]):
            ans=ans+1
ans = ans+n
print(ans)

蓝桥杯python组国赛复盘_第11张图片
这道题应该是一道数位DP的题,前两周上课设的时候摸鱼打了个比赛,碰到了一个原题,当时写了个爆搜,当然是超时了,之后也没有补题,爆搜是会超时的所以又写了个大暴力

n,k = list(map(int,input().split()))
ans = 0
for i in range(1,n+1):
    s = format(i,'b')
    if s.count('1')==k:
        ans+=1
print(ans)

写的真暴力,要是补题了这个原题应该可以秒掉吧

蓝桥杯python组国赛复盘_第12张图片
蓝桥杯python组国赛复盘_第13张图片
这道题正解在考场上没出来,就用栈模拟了一下其中的过程,得分大概是60%或者是40%

n,m = list(map(int,input().split()))
a = input()
s = [a[i] for i in range(len(a))]
def turn(l,r):
    for i in range(l,r+1):
        if s[i]=='(':
            s[i]=')'
        elif s[i]==')':
            s[i]='('
def check(p):
    q = []
    res = 0
    for i in range(p,n):
        if s[i]=='(':
            q.append('(')
        elif s[i]==')':
            if len(q)==0:
                return res
            elif len(q)==1:
                res = i+1
                q.pop(0)
            elif len(q)>1:
                q.pop(0)
    return res
for i in range(m):
    x = list(input().split())
    if x[0]=='1':
        turn(int(x[1]),int(x[2]))
    elif x[0]=='2':
        ans = check(int(x[1])-1)
        print(ans)


你可能感兴趣的:(比赛)