The 14th Lanqiao Cup Competition Software Competition Provincial Competition (Python University Group A)

2023 Lanqiao Cup  Provincial Competition Real Questions
Python University Group A

        Test question A: Special date
        Test question B: Distributing candy
        Test question C: Three Kingdoms Game
        Test question D: Average
        Test question E: Flip
        Test question F: Submatrix
        Test question G: Sum of factorials
        Test question H: Strange numbers
        Test question I: The size of the subtree
        Test question J: Inverse exclusive OR 01 string


Question A: Special Date (5 points)

【Problem Description】

        are being recorded are taken are as follows:                               Record a date as yy, year mm, month dd and day, count from January 1, 2000 to January 1, 2000000: How many dates are there such that the year yy is a multiple of the month mm and is also a multiple of dd.

【Answer submission】

        This is a fill-in-the-blank question, you just need to calculate the result and submit it. The result of this question is an integer. When submitting the answer, only output this integer. No points will be awarded for outputting redundant content.

【Analysis and Method】

        The simplest and crudest method is to directly traverse from January 1, 2000 to January 1, 2000000. It is recommended to use C++ to write using this method, which will run faster and Python can run at full capacity. Although Python has a relatively easy-to-use datetime package, Python's datetime object can represent the date range from January 1, 1 AD to December 9999 AD. 31st. The maximum date given by the question has been exceeded, and an error is reported as soon as I run it. Therefore, it is more convenient and less error-prone to run directly violently.

[Python program code]

mon = [0,31,28,31,30,31,30,31,31,30,31,30,31]
def run(x):  #判断是否为闰年
    if x%400==0 or (x%4==0 and x%100!=0):
        return True
    return False
res = 0
for year in range(2000,2000000):
    if run(year):
        mon[2]=29
    else:
        mon[2]=28
    for mm in range(1,13):
        for dd in range(1,mon[mm]+1):
            if year%mm==0 and year%dd==0:
                res += 1
print(res+1)  #前面只迭代到了1999999年12月31日,最后2000000年1月1日也是一个答案

Final result:35813063

 Extension: How to use datetime objects

from datetime import datetime, timedelta
# 定义开始和结束日期
start_date = datetime(2023, 1, 1)
end_date = datetime(2024, 1, 1)
# 定义时间间隔
delta = timedelta(days=1)
# 迭代日期范围
while start_date <= end_date:
    year = start_date.year
    mon = start_date.month
    day = start_date.day
    print("%04d-%02d-%02d"%(year,mon,day))
    #print(start_date.strftime("%Y-%m-%d"))
    start_date += delta

Question B: Divide candies (5 points)

【Problem Description】

        There are 9 and 16 candies of two kinds of candies respectively. They must be distributed to 7 children. The total number of candies received by each child is at least 2 and at most 5. How many different ways are there to divide the candies? All must be completed.
        If one of the children does not receive exactly the same candies in the two plans, the two plans are counted as different plans.

【Answer submission】

        This is a fill-in-the-blank question, you just need to calculate the result and submit it. The result of this question is an integer. When submitting the answer, only output this integer. No points will be awarded for outputting redundant content.

【Analysis and Method】

        It is known that the number of two kinds of candies is 9 and 16 respectively. Each child is divided into at least 2 candies and at most 5 candies. From this, the distribution situation of each medium (how many candies a and b are divided) can be calculated. Enumerate them. The following table:

a 0 1 2 0 1 2 3 0 1 2 3 4 0 1 2 3 4 5
b 2 1 0 3 2 1 0 4 3 2 1 0 5 4 3 2 1 0

        Therefore, based on the known situation, a violent search method can be used, plus a necessary condition for the establishment of the plan. Once all the candies are finished, the establishment of the plan can be confirmed.

[Python program code]

import sys
sys.setrecursionlimit(1000000)  #设置递归深度可以不需要
a = [0,1,2,0,1,2,3,0,1,2,3,4,0,1,2,3,4,5]
b = [2,1,0,3,2,1,0,4,3,2,1,0,5,4,3,2,1,0]
ans = 0
def dfs(u,c1,c2):
    global ans
    if u==7:
        if not c1 and not c2:  #判断是否全部分完
            ans += 1
    else:
        for i in range(len(a)):
            if c1>=a[i] and c2>=b[i]:
                dfs(u+1,c1-a[i],c2-b[i])
dfs(0,9,16)
print(ans)

Final result:5067671


Question C: Three Kingdoms Game (10 points) 

【Problem Description】

        Xiaolan is playing a game. In the game, the three countries Wei (X), Shu (Y), and Wu (Z) each have a certain number of soldiers X, Y, and Z (it can be considered at the beginning that they are all 0). The game has n events that may be sent. Each event is independent of each other and can only be sent once at most. When the i-th event is sent, X, Y, and Z will increase respectivelyA_{i} B_{i} C_{i}.< /span>

        When the game is over (so the occurrence of the event has been determined), if one of X, Y, and Z is greater than the sum of the other two, we consider it to have won. For example, when If there is no situation where a country wins, output -1.

【Input format】

        The first line of input contains an integer n.
        The second line contains n integers representing A. Adjacent integers are separated by a space.
        The third line contains n integers representing B. Separate by a space
        The fourth line contains n integers representing C, and use a space to separate adjacent integers

[Output format]

        One line of output contains an integer representing the answer.

[Sample input]

3
1 2 2
2 3 2
1 0 7

[Sample output]

2

[Evaluation use cases and scale]

        For 40% of the evaluation cases, n < 500;
        For 70% of the evaluation cases, n <5000; For all evaluation cases, n<10^{5},1\leqslant A_{i} ,B_{i},C_{i}\leqslant 10^{9}.

【Analysis and Method】

        First of all, make it clear that the end of the game (so whether or not something happened has been determined) only means that 1, 2...n will happen in the game at one time. A situation such as X>Y+Z may occur during the process, but this does not mean that a certain Wei country has won. Instead, we have to wait until everything has happened to compare the situation of Once you understand it, the difficulty drops straight away. Therefore, we can enumerate the number of things that the three countries Wei, Shu, and Wu want to win the most, and then taking the maximum value is the answer.
        Suppose Wei wins: Let new_X =[Ai - Bi - Ci]. 1<=i<=n
        In order to maximize the number of events, it is necessary to start from Where new_Xi is the largest, sum_X += new_Xi
        begins to occur. When sum_X<=0, it ends.

【Python program code】       

n = int(input())
A = list(map(int,input().split()))
B = list(map(int,input().split()))
C = list(map(int,input().split()))
new_X = sorted([ A[_] - B[_] - C[_] for _ in range(n) ],reverse=True)
new_Y = sorted([ B[_] - A[_] - C[_] for _ in range(n) ],reverse=True)
new_Z = sorted([ C[_] - A[_] - B[_] for _ in range(n) ],reverse=True)
ans,resX,resY,resZ,sum_X,sum_Y,sum_Z = 0,0,0,0,0,0,0
for i in range(n):
    sum_X,sum_Y,sum_Z =  sum_X + new_X[i], sum_Y + new_Y[i], sum_Z + new_Z[i]
    resX = resY = resZ = i + 1
    if sum_X>0:ans = max(ans,resX)
    if sum_Y>0:ans = max(ans,resY)
    if sum_Z>0:ans = max(ans,resZ)
    if sum_X<=0 and sum_Y<=0 and sum_Z<=0:break
print(ans if ans else -1)

Question D: Average (10 points)

【Problem Description】

        There is an array of length n (n is a multiple of 10), and each number a is an integer in the interval [0, 9]. Xiao Ming found that the number of occurrences of each number in the array was uneven, and the cost of changing the i-th number was bi. He wanted to change the values ​​of several numbers so that the number of occurrences of these 10 numbers was equal (all equal to n/10). What is the minimum sum of the costs?

【Input format】

        The first line of input contains a positive integer n.
        The next n lines, the i-th line includes two integers ai, bi, separated by a space.

[Output format]

        The output consists of a positive integer representing the answer.

[Sample input]

10
1 1
1 2
1 3
2 4
2 5
2 6
3 7
3 8
3 9
4 10

[Sample output]

27

[Sample description] 

        only changing the 1, 2, 4, 5, 7, and 8th numbers will cost 1+2+4+5+7+8=27

[Test cases and scale]

        For 20% of the evaluation cases, n<=1000
        For all evaluation cases, n<=10^{5} ,0<b_{i}<=2*10^{5}

【Analysis and Method】

        This should be the simplest programming question, avg = n/10, traverse 0~9, if the number of a certain number is greater than avg, you need to change num[i] - avg numbers, directly select all i numbers to change with the least cost The first num[i]-avg numbers are enough.

 【Python program code】

n = int(input())
num,avg,res = [[]for i in range(10)],n//10,0
for i in range(n):
  a,b = map(int,input().split())
  num[a].append(b)
for i in range(10):
  if len(num[i])>avg:
    num[i].sort()
    for _ in range(len(num[i])-avg):
      res += num[i][_]
print(res)

Question E: Flip (15 points)

【Problem Description】

        Xiaolan arranged n pieces of black and white chess pieces in a row. He imagined a string of 01 T with a length of n in his mind. He found that if the black chess pieces were regarded as 1 and the white chess pieces were regarded as 0, then A row of chess pieces is also a string of 01 S with length n.
        Xiaolan decided that if a chess piece is found in S that is different from the chess pieces on both sides of it, it can be flipped into another color. In other words, if there is a substring 101 or 010 in S, you can choose to change it to 111 and 000 respectively. This operation can be repeated infinitely.
        Xiao Lan wants to know the minimum number of flips to turn S into exactly the same as

【Input format】

        The input contains multiple groups of data
        The first line of the input contains a positive integer D representing the number of data groups
        Each of the following 2D lines contains a 01 String, every two lines is a set of data, the 2i-1th line is the Ti of the i-th set of data, the 2ith line is the Si of the i-th set of data, the degrees of Si and Ti are both n.

[Output format]

        For each set of data, the output line contains an integer, indicating the answer. If the answer does not exist, please output -1.

[Sample input]

2
1000111
1010101
01000
11000

[Sample output]

2
-1

[Evaluation use cases and scale]

        For 20% of the evaluation use cases, 1<=\sum ni<=10.

        For all evaluation use cases, it is guaranteed1<=\sum ni<=10^{6},ni>0.

【Analysis and Method】

        If there are 101 and 010 in the S given by the question, it can be changed to 111 and 000 respectively. That is, if any three consecutive digits are different from the middle to the left and right sides, the middle one can be made the same as the left and right sides. If 101 or 010 is changed into 111 or 000, we can find that it will not affect other positions, that is, there will be no chain reaction. That is, when comparing Si and Ti, ifS_{i}!=T_{i}, then determine whether Si meets the conditions for flipping. If it does not meet the conditions for flipping, S cannot become T.

[Python program code]

tt = int(input())
for i in range(tt):
  t = list(input())#把s变成t
  s = list(input())
  cnt,flag = 0,1
  for i in range(len(s)):
    if s[i]!=t[i]:
      if i-1>=0 and i+1<len(s) and s[i+1]!=s[i] and s[i-1]!=s[i]:
        s[i],cnt = s[i+1],cnt+1
      else:
        flag = 0;break
  print(cnt if flag else -1)

Question F: Submatrix (15 points)

[Title description]

        Given a nxm (n rows and m columns) matrix. Let the value of a matrix be the product of the maximum and minimum values ​​of all its numbers. Find the sum of the values ​​of all submatrices of size a xb (a rows and columns) of the given matrix.
        The answer may be very large, you only need to output the result of the answer modulo 998244353.

【Input format】

        The first line of input contains four integers representing n, m, a, and b respectively. Adjacent integers are separated by a space. Next
n lines each contain m integers. Adjacent integers are separated by a space to represent each number Aij in the matrix.

[Output format]

        One line of output contains an integer representing the answer.

[Sample input]

2 3 1 2
1 2 3
4 5 6

[Sample output]

58

[Sample description]

        1x2+2x3+4x5+5x6=58.

[Evaluation use case scale and agreement]

        For 40% of the evaluation use cases, 1<=n,m<=100.
        For 70% of the evaluation use cases, 1<=n,m<=500. a>
        For all evaluation use cases, 1<=a<=n<=1000,1<=b<=m<=1000.1<=A_{ij}<=10^{9}

【Analysis and Method】

        Violence obviously cannot pass all test data. You need to get the maximum and minimum values ​​of each a*b-sized matrix. You can first consider getting the maximum and minimum values ​​in a window with a row length of b, and then based on this Find the maximum and minimum values ​​of the window with length a in each column. You can preprocess the maximum and minimum values ​​in each sub-matrix. Requiring the maximum and minimum values ​​in a sliding window is a basic monotonic queue problem.

[Python Programs and Codes]

n, m, a, b = map(int, input().split())
s,num_max,num_min,n_max,n_min,res = [[0] * (n + 2) for _ in range(n + 2)],[],[],[],[],0
for i in range(1, n + 1):
    s[i][1:m + 1] = map(int, input().split())
def get_min(a, k, m):
    tep,q,hh,tt = [],[0]*1010,0,-1
    for i in range(1, m + 1):
        if hh <= tt and q[hh] <= i - k: hh += 1  # 判断是否出了窗口
        while hh <= tt and a[i] <= a[q[tt]]: tt -= 1
        tt,q[tt] = tt + 1,i
        if i - k >= 0: tep.append(a[q[hh]])
    return tep
def get_max(a, k, m):
    tep,q,hh,tt = [],[0]*1010,0,-1
    for i in range(1, m + 1):
        if hh <= tt and q[hh] <= i - k: hh += 1  # 判断是否出了窗口
        while hh <= tt and a[i] >= a[q[tt]]: tt -= 1
        tt,q[tt] = tt + 1,i
        if i - k >= 0: tep.append(a[q[hh]])
    return tep
for i in range(1, n + 1):
    temp = [0] + get_max(s[i][:m + 1], b, m)
    num_max.append(temp)
    temp = [0] + get_min(s[i][:m + 1], b, m)
    num_min.append(temp)
for i in range(1, m - b + 2):
    t1 = [0]
    for _ in range(n):
        t1.append(num_max[_][i])
    t1.append(0)
    temp = get_max(t1, a, n)
    n_max.append(temp)
    t2 = [0]
    for _ in range(n):
        t2.append(num_min[_][i])
    t2.append(0)
    temp = get_min(t2, a, n)
    n_min.append(temp)
for i in range(len(n_max)):
    for j in range(len(n_max[0])):
        res += n_max[i][j] * n_min[i][j]
print(res)

Question G: Sum of factorials (20 points)

【Problem Description】

        Given n numbersA_{i}, what is the largest m that can satisfy that m! is a factor of\sum_{i=1}^{m}(A_{i}!), where m! represents the factor of m Factorial, that is 1x2x3x···xm.

【Input format】

        The first line of input contains an integer n.
        The second line contains n integers, representing A_{i} respectively. Adjacent integers are separated by a space.

[Output format]

        or                                             are given a line containing an integer representing the answer.

[Sample input]

3
2 2 2

[Sample output]

3

[Evaluation use case scale and agreement]

        For 40% of the evaluation use cases, n<=5000.
        For all evaluation use cases, 1<=n<=10^{5},1<=A_{i}<=10^{9}.

【Analysis and Method】

        First, let’s clarify\frac{K_{1}A! + K_{2}B! +\cdots K_{i}Z! }{m!}=num and the conditions that hold when num in this formula is an integer. By extracting common factors from the numerator, we get the common factor asS!, then The largest value of m is S. Therefore, to solve this problem, we only need to simulate the factorial conversion.

[Python program code]

n = int(input())
a = list(map(int,input().split()))
a.sort()
st,i,cnt = a[0],0,0
while i<n:
  while i<n and a[i]==st:
    cnt += 1
    i += 1
  if cnt and cnt%(st+1)==0:
    cnt,st = cnt//(st+1),st+1
    if i==n:
      while cnt and cnt%(st+1)==0:
        cnt,st = cnt//(st+1),st+1
  else:
    break
print(st)

Question H: Strange Numbers (20 points)

【Problem Description】

        Xiaolan has been looking for some strange numbers recently. The odd numbers are odd numbers, and the even numbers are even numbers. At the same time, the sum of any five consecutive digits of these numbers is not greater than m.
        For example, when m=9, 10101 and 12303 are strange numbers, but 12345 and 11111 are not.
Xiaolan wants to know how many of the above-mentioned strange numbers with length n are there. You just need to output the answer modulo 998244353.

【Input format】

        ​ ​ ​ Enter a line containing two integers n, m, separated by a space.

[Output format]

        Output a line containing an integer representing the answer.

[Sample input]

5 5

[Sample output]

6

 【Evaluation use case scale and agreement】

        For 30% of the evaluation use cases, n<=12;
        For 60% of the evaluation use cases, n<=5000;
        For all Evaluation use case, 5<=n<=2*10^{5},0<=m<=50.

【Analysis and Method】

         It is necessary to continuously verify whether the sum of the digits on the 5 digits is greater than m. Set the status F_{i,a,b,c,d}, indicating that the number on the i-3rd digit is a, i-2: b , i-1: c, i: d, how many strange numbers are there. So there are:

F_{i,a,b,c,d} =\sum F_{i-1,e,a,b,c} , a+b+d+e<=m

        Time complexityO(5^{5}n) is about6.25*10^{8} operations, and there is a high probability that it will not pass. Therefore, consider maintaining the prefix sum of F in the second dimension.

g_{i,a,b,c,d} = \sum_{a}^{j=0}F_{i,j,b,c,d}

        Transfer equation:

g_{i,a,b,c,d} = g_{i,a-1,b,c,d}+g_{i-1},max(0,min(9,m-a-b-c-d))),a,b,c

        The time complexity is O(5^{4}n), which is about 1.25*10^{8} operations, which can be directly skipped by C++. Python may be stuck. After testing on the official website, C++ only takes 40ms, and Python only takes 70%. This question is indeed the most difficult question in this category.

[Python program code]

M,mod,ans,p,q = 12,998244353,0,1,0
n, m= map(int, input().split())
g = [[[[[0 for _ in range(M)] for _ in range(M)] for _ in range(M)] for _ in range(M)] for _ in range(2)]
for a in range(p, 10, 2):      #维护二维的前缀和? 预处理出前4位的情况
    for b in range(q, 10, 2):
        for c in range(p, 10, 2):
            for d in range(q, 10, 2):
                g[0][a + 2][b][c][d] = g[0][a][b][c][d] + int(a + b + c + d <= m)
for i in range(5, n + 1):     #从第五位开始
    p,q= p^1,q^1
    for a in range(p, 10, 2):
        for b in range(q, 10, 2):
            for c in range(p, 10, 2):
                for d in range(q, 10, 2):
                    f = m - a - b - c - d  #计算f值
                    if q != (f & 1):f -= 1   #余数f与当前位置的奇偶性不同则f--   q表示奇偶情况
                    if f > 8 + p:f = 8 + q   #控制余数f在0~9范围内
                    g[i % 2][a + 2][b][c][d] = (g[i % 2][a][b][c][d] + (0 if f < q else g[(i + 1) % 2][f + 2][a][b][c])) % mod
for b in range(q, 10, 2):
    for c in range(p, 10, 2):
        for d in range(q, 10, 2):
            f = m - b - c - d
            if f < p:continue
            if p != (f & 1):f -= 1
            if f > 8 + p:f = 8 + p
            ans = (ans + g[n % 2][f + 2][b][c][d]) % mod
print(ans)

[C language program code]

#include <stdio.h>
const int M = 12, mod = 998244353;
int n, m, ans, g[2][M][M][M][M];
int main() {
    scanf("%d %d", &n, &m);
    int p = 1, q = 0;
    //维护二维的前缀和 预处理出前4位的情况 
    for (int a = p; a < 10; a += 2)
        for (int b = q; b < 10; b += 2)
            for (int c = p; c < 10; c += 2)
                for (int d = q; d < 10; d += 2) {
                    g[0][a + 2][b][c][d] = g[0][a][b][c][d] + (a + b + c + d <= m);
                }
    //从第五位开始 
    for (int i = 5; i <= n; ++i) {
        p ^= 1, q ^= 1;  //移动一位奇数偶数的相对位置发送变化 
        for (int a = p; a < 10; a += 2)
            for (int b = q; b < 10; b += 2)
                for (int c = p; c < 10; c += 2)
                    for (int d = q; d < 10; d += 2) {
                        int f = m - a - b - c - d;   //计算f值 
                        if (q != (f & 1)) --f;   //余数f与当前位置的奇偶性不同则f--    q表示奇偶情况 
                        if (f > 8 + p) f = 8 + q;   // 控制余数f在0~9范围内
						//状态转移 
                        g[i & 1][a + 2][b][c][d] = (g[i & 1][a][b][c][d] + (f < q ? 0 : g[~i & 1][f + 2][a][b][c])) % mod;
                    }
    }
    for (int b = q; b < 10; b += 2)
        for (int c = p; c < 10; c += 2)
            for (int d = q; d < 10; d += 2) {
                int f = m - b - c - d;
                if (f < p) continue;
                if (p != (f & 1)) --f;
                if (f > 8 + p) f = 8 + p;
                ans = (ans + g[n & 1][f + 2][b][c][d]) % mod;
            }
    printf("%d", ans);
}

Question I: Subtree size (25 points)

【Problem Description】

        ​​​​Given a complete m-tree containing n nodes, the nodes are numbered in order from root to leaf and from left to right. For example, the figure below is a complete 3-tree with 11 nodes.

        You need to find the number of nodes in the subtree of the k-th node.​ 

【Input format】

        The input contains multiple sets of queries.
        The first line of input contains an integer T, indicating the number of queries.
        Next line, each line contains three integers n, m, k, representing a set of queries.

[Output format]

        Output T lines, each line contains an integer representing the answer to the corresponding query.

[Sample input]

3
1 2 1
11 3 4
74 5 3

[Sample output]

1
2
24

[Use case scale and convention]

        For 40% of the evaluation use cases, T<=50,n<=10^{6},m<=16.
        For all evaluation use cases, 1<=T<=10^{5},1<=k<=n<=10^{9},2<=m<=10^{9}.

【Analysis and Method】

        ​ ​ ​ Observing the scale of use cases, we can see that it is impossible to build a tree, so we need to start with the characteristics of a complete m-ary tree. As shown below:

        ​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​? ​ or ​​ first consider the method to find the number of nodes in the subtree of node 3, set a left and right pointers l, r to point to the numbers of the leftmost and rightmost nodes of this level of subtree respectively. At this time l=r=3. Expand one level downward each time and determine whether the node number on the right side of the bottom layer of the k node is greater than n. If it is greater than n, it means that the maximum depth has been reached. At the same time, it is determined whether the number of the leftmost node is less than or equal to n. , if it is less than or equal to n, then the lowest level has n - ((l-1)*m+1) nodes in total, and the loop exits. If it is less than or equal to n, continue to expand downward. At this time, r=(r*m+1), l=(l-1)*m+2.

[Python program code]

T = int(input())
def solve(n,m,k):
  l,r,res,mk = k,k,0,1
  while True:
    res += mk
    if r*m+1>n:
      if (l-1)*m+2<=n:
        res += n- ((l-1)*m+1)
      break
    mk*=m
    r = (r*m+1)
    l = (l-1)*m+2
  return res
for _ in range(T):
  n,m,k = map(int,input().split())
  print(solve(n,m,k))

Test question J: Reverse exclusive OR 01 string (25 points)

【Problem Description】

        There is initially an empty 01 string, and each operation can add 0 or 1 to the left or right side. You can also perform an inverse XOR operation on the entire string: take s' = rev(s), where s is the current 01 string, which means bit-by-bit XOR, rev(s) means flipping s, that is to say, take Center position and swap all symmetrical characters of the two positions. For example, rev(0101)=1010, rev(010) = 010, rev(0011)=1100.
        The anti-XOR operation can be used at most once (you can not use it, or you can use it once). Given a 01 string T, ask how many 1s need to be added at least to get T from an empty 01 string. In this question, any number of 0s can be added.

【Input format】

The input line contains a string of 01 representing the given T.

[Output format]

One line of output contains an integer, indicating the minimum number of 1's that need to be added.

[Sample input]

00111011

[Sample output]

3

[Evaluation use cases and scale]

        For 20% of the evaluation use cases, |T|<=10, for 40% of the evaluation use cases |T|<=500;
        For 40% of the evaluation use cases, |T|<=5000;For 80% of the evaluation use cases|T|<=10^{5}
        For all evaluation use cases,1<=|T|<=10^{6}, it is guaranteed that T only contains 0 and 1.

【Analysis and Method】

        First, understand the anti-XOR operation. In fact, a palindrome sequence with an even length only requires half the number of 1s to be created through the anti-XOR operation. An odd palindrome string requires that the central character cannot be is 1, it can only be 0 that can be created with half the number of 1's via the anti-XOR operation. Therefore, the question can be transformed into finding a palindrome string that satisfies the above conditions and uses the largest number of 1s. The algorithm for quickly finding the length of a palindrome string is the horse-drawn cart algorithm (Manacher). Through the horse-drawn cart algorithm, a d[i] array can be preprocessed , represents the radius of the palindrome string centered on i. Therefore, using prefix and preprocessing optimization solution can reduce the complexity to O(n), but the constant is relatively large. It’s still relatively easy to get stuck using Python. The following code is stuck at 2 points on the C language network. If you use C++, it can be done in seconds.

[Python program code]

a = input()
n, k = len(a), 1
s = ['$', '#']
for i in range(n):
    k += 2
    s.append(a[i])
    s.append('#')
n = k
# 以上操作可以使新字符串为奇字符串
# s[0]="$"是设置的哨兵
# 设置数字1的前缀和函数
pre = [0] * (n + 1)
for i in range(1, n + 1):
    if s[i] == '1':
        pre[i] = pre[i - 1] + 1
    else:
        pre[i] = pre[i - 1]
al = pre[n]
d = [0] * (n + 1)
co = 0
# 回文半径d[i],即以i为中心半径为d[i],包括中心i
def get_d():
    global d
    global co
    d[1] = 1
    l, r = 0, 1
    for i in range(2, n + 1):
        if i <= r:
            d[i] = min(d[r - i + l], r - i + 1)
        while i + d[i] <= n and i - d[i] >= 0 and s[i - d[i]] == s[i + d[i]]:
            d[i] += 1
        if i + d[i] - 1 > r:
            l = i - d[i] + 1
            r = i + d[i] - 1
        if s[i] != '1':
            co = max(co, pre[i - 1] - pre[i - d[i]])
get_d()
print(al - co)

[C++ program code]

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
    string a;
    cin >> a;
    int n = a.size(), k = 1;
    vector<char> s(n * 2 + 3, '#');
    s[0] = '$';
    vector<int> pre(n * 2 + 3, 0);
    for (int i = 0; i < n; ++i) {
        k += 2;
        s[k - 1] = a[i];
    }
    n = k;
    for (int i = 1; i <= n; ++i) {
        if (s[i] == '1') {
            pre[i] = pre[i - 1] + 1;
        } else {
            pre[i] = pre[i - 1];
        }
    }
    int al = pre[n];
    vector<int> d(n + 1, 0);
    int co = 0;
    d[1] = 1;
    int l = 0, r = 1;
    for (int i = 2; i <= n; ++i) {
        if (i <= r) {
            d[i] = min(d[r - i + l], r - i + 1);
        }
        while (i + d[i] <= n && i - d[i] >= 0 && s[i - d[i]] == s[i + d[i]]) {
            d[i] += 1;
        }
        if (i + d[i] - 1 > r) {
            l = i - d[i] + 1;
            r = i + d[i] - 1;
        }
        if (s[i] != '1') {
            co = max(co, pre[i - 1] - pre[i - d[i]]);
        }
    }
    cout << al - co << endl;
    return 0;
}

Guess you like

Origin blog.csdn.net/w2563216521/article/details/133161310