2016 7th Blue Bridge Cup C/C++ Group A Question Solutions

 

first question

Netizen age

A new friend met a netizen.
When asked about the age, his netizen said:
"My age is a two-digit number, and I am 27 years older than my son.
If I swap the two digits of my age, it happens to be my son's age."

Please calculate: How many possible situations are there for the age of a netizen?

Tip: 30 years old is one of the possibilities.

Please fill in the number of possible situations.
Note: What you submit should be an integer, do not fill in any extra content or explanatory text.

7

Second question

Birthday candles

A certain person has held a birthday party every year since a certain year, and every time he blows out the same number of candles as his age.

Counting now, he blew out a total of 236 candles.

Excuse me, at what age did he start his birthday party?

Please fill in the age when he started the birthday party.
Note: What you submit should be an integer, do not fill in any extra content or explanatory text.


26

Third question

Square fill

The following 10 grids
   +--+--+--+
   | | | |
+--+--+--+--+
| | | | |
+--+--+--+--+
| | | |
+--+--+--+

(If there are problems with the display, you can also refer to [Figure 1.jpg])

Fill in the numbers from 0 to 9. Requirement: Two consecutive numbers cannot be adjacent.
(Left and right, up and down, and diagonally are all adjacent)

How many possible filling schemes are there?

Please fill in an integer representing the number of plans.
Note: What you submit should be an integer, do not fill in any extra content or explanatory text.

1580

#include<iostream>
#include<cmath>
using namespace std;
int a[3][4];
bool geted[10]={false};
int cnt=0;

bool side(int x,int y)
{
    for(int i=x-1;i<=x+1;i++)
    {
        for(int j=y-1;j<=y+1;j++)
        {
            if(i<0||i>2||j<0||j>3 || (i==x&&j==y))
                continue;
            else if(abs(a[x][y]-a[i][j])<=1)
                return false;
        }
    }
    return true;
}

void dfs(int x,int y)
{
    if(x==2&&y==3)
    {
        cnt++;
        return;
    }
    if(y>3)
    {//换行
        x+=1;
        y=0;
    }

    for(int i=0;i<10;i++)
    {
        if(geted[i]==false)
        {
            geted[i]=true;
            a[x][y]=i;
            if(side(x,y)==true)
            {
                dfs(x,y+1);
            }
            geted[i]=false;
            a[x][y]=-4;
        }
    }
    return;
}
int main()
{

    for(int i=0;i<3;i++)
    {
        for(int j=0;j<4;j++)
        {
            a[i][j]=-4;
        }
    }

    dfs(0,1);
    cout<<cnt<<endl;
    return 0;
}

Fourth question

Quick sort

Sorting is often used in various situations.
Quick sort is a very commonly used and efficient algorithm.

The idea is: first select a "ruler" and
use it to sift through the entire queue
to ensure that the elements on the left are not larger than it, and the elements on the right are not smaller than it.

In this way, the sorting problem is divided into two sub-intervals.
Then sort the subintervals separately.

The following code is an implementation, please analyze and fill in the missing code in the underlined part.


#include <stdio.h>

void swap(int a[], int i, int j)
{
    int t = a[i];
    a[i] = a[j];
    a[j] = t;
}

int partition(int a[], int p, int r)
{
    int i = p;
    int j = r + 1;
    int x = a[p];
    while(1){
        while(i<r && a[++i]<x);
        while(a[--j]>x);
        if(i>=j) break;
        swap(a,i,j);
    }
    swap(a,p,j);
    return j;
}

void quicksort(int a[], int p, int r)
{
    if(p<r){
        int q = partition(a,p,r);
        quicksort(a,p,q-1);
        quicksort(a,q+1,r);
    }
}
    
int main()
{
    int i;
    int a[] = {5,13,6,24,2,8,19,27,6,12,1,17};
    int N = 12;
    
    quicksort(a, 0, N-1);
    
    for(i=0; i<N; i++) printf("%d ", a[i]);
    printf("\n");
    
    return 0;
}


Note: Only fill in the missing content, do not write any code or explanatory text on the title.

Fifth question

Eliminate the tail one

The following code turns the rightmost consecutive 1s in the binary representation of an integer to 0.
If the last digit is 0, the original number remains unchanged.

If you use the test data in the code, it should output:
00000000000000000000000001100111 00000000000000000000000001100000
00000000000000000000000000001100 00000000000000000000000000001100

Please read the program carefully and fill in the missing codes in the underlined part.


#include <stdio.h>

void f(int x)
{
    int i;
    for(i=0; i<32; i++) printf("%d", (x>>(31-i))&1);
    printf("   ");
    
    x =x&(x+1);
    
    for(i=0; i<32; i++) printf("%d", (x>>(31-i))&1);
    printf("\n");    
}

int main()
{
    f(103);
    f(12);
    return 0;
}

Note: Only fill in the missing content, do not write any code or explanatory text on the title.

Sixth question

Winter homework

Now the math problems in elementary school are not so fun.
Check out this winter homework:

   □ + □ = □
   □-□ = □
   □ × □ = □
   □ ÷ □ = □
   
   (If it is not displayed, please refer to [Figure 1.jpg])
   
Each square represents a number from 1 to 13, but it cannot repeat.
For example:
 6 + 7 = 13
 9-8 = 1
 3 * 4 = 12
 10/2 = 5

And: 
 7 + 6 = 13
 9-8 = 1
 3 * 4 = 12
 10/2 = 5

Even two solutions. (Addition and multiplication are different solutions after the commutative law)
 
How many solutions have you found?


Please fill in an integer representing the number of plans.
Note: What you submit should be an integer, do not fill in any extra content or explanatory text.
64

#include<iostream>
using namespace std;

bool geted[14]={false};
int cnt=0;

void dfs(int row)
{
    if(row==5)
    {
        cnt++;
        return;
    }
    for(int i=1;i<=13;i++)
    {
        for(int j=1;j<i;j++)
        {
            if(geted[i]==true || geted[j]==true)
                continue;
            geted[i]=geted[j]=true;
            switch(row)
            {
                case 1:
                    if(i+j<=13 && geted[i+j]==false)
                    {
                        geted[i+j]=true;
                        dfs(2);
                        geted[i+j]=false;

                    }
                    break;
                case 2:
                    if(geted[i-j]==false)
                    {
                        geted[i-j]=true;
                        dfs(3);
                        geted[i-j]=false;
                    }
                    break;
                case 3:
                    if(i*j<=13 && geted[i*j]==false)
                    {
                        
                        geted[i*j]=true;
                        dfs(4);
                        geted[i*j]=false;
                    }
                    break;
                case 4:
                    if(i%j==0 && geted[i/j]==false)
                    {
                        geted[i/j]=true;
                        dfs(5);
                        geted[i/j]=false;
                    }
                    break;
            }
            geted[i]=geted[j]=false;
        }
    }
    return;
}

int main()
{
    dfs(1);
    cout<<cnt*4<<endl;
    return 0;
}

 

Seventh question

Cut stamps

As shown in [Picture 1.jpg], there are 12 stamps with 12 zodiac signs connected together.
Now you have to cut out 5 sheets from it, and the requirements must be connected.
(Just connecting one corner does not count as connecting) For
example, in [Picture 2.jpg], [Picture 3.jpg], the part shown in pink is a qualified cut. (The picture is too lazy to post)

Please calculate how many different clipping methods there are.

Please fill in an integer representing the number of plans.

116 (I was violent in this question. After reading the dfs solution, I felt that they were all good. If it is violent, please pay attention to the details)

#include<iostream>
#include<cmath>
using namespace std;
int b[5];
int cnt=0;
void test()
{
    int connect=0;
    for(int i=0;i<5;i++)
    {
        int num=0;
        int row1=b[i]/4;
        int col1=b[i]%4;
        for(int j=0;j<5;j++)
        {//判断是否b[i]邮票是不是独立的,和几张邮票相邻
            if(i==j)
                continue;
            int row2=b[j]/4;
            int col2=b[j]%4;

            if((row1==row2 && abs(col1-col2)==1) || (col1==col2 && abs(row1-row2)==1))
            {
                num++;
            }
        }
        if(num==0)
            return;
        connect+=num;
    }
    if(connect>6)//考虑可能出现两张邮票相连和三张邮票相连 两个连通图 这样子接触面最多3*2=6
        cnt++;
    return;
}
int main()
{
    for(int i1=0;i1<=11-4;i1++)
    {
        b[0]=i1;
        for(int i2=i1+1;i2<=11-3;i2++)
        {
            b[1]=i2;
            for(int i3=i2+1;i3<=11-2;i3++)
            {
                b[2]=i3;
                for(int i4=i3+1;i4<=11-1;i4++)
                {
                    b[3]=i4;
                    for(int i5=i4+1;i5<=11;i5++)
                    {
                       b[4]=i5;
                        test();
                    }
                }
            }
        }
    }
    cout<<cnt<<endl;
    return 0;
}

Question 8

Sum of four squares

The Four Squares Theorem, also known as Lagrange's Theorem:
Every positive integer can be expressed as the sum of the squares of at most 4 positive integers.
If 0 is included, it can be expressed as the sum of the squares of 4 numbers.

For example:
5 = 0^2 + 0^2 + 1^2 + 2^2
7 = 1^2 + 1^2 + 1^2 + 2^2
(The ^ symbol means power)

For a given positive integer, there may be multiple representations of the sum of squares.
You are required to sort the 4 numbers:
0 <= a <= b <= c <= d
and arrange all possible representations in ascending order by a, b, c, d as the joint primary key, and finally output the first representation


The program input is a positive integer N (N<5000000)
. 4 non-negative integers are required to be output, sorted from small to large, separated by spaces

For example, input:
5
, the program should output:
0 0 1 2

For another example, input:
12
, the program should output:
0 2 2 2

For another example, input:
773535
, the program should output:
1 1 267 838

Resource agreement:
peak memory consumption <256M
CPU consumption <3000ms

Please output strictly according to the requirements, and don't superfluously print the extra content like: "please enter...".

Remember to prevent timeout

#include<iostream>
#include<cmath>
#include<map>
using namespace std;
int main()
{//这道题主要要解决超时
    int n;
    cin>>n;
    int s=sqrt(n)+1;
    int i1,j1,k1;
    map<int,int> m;
    for(int i=0;i<s;i++)
    {
        for(int j=i;j<s;j++)
        {//设置m主要是为了将三层循环变得简单点
            m[i*i+j*j]=1;//记录可以有两个数平方和得到的数字
        }
    }
    
    for(int i=0;i<s;i++)
    {
        i1=i*i;
        for(int j=i;j<s;j++)
        {
            j1=j*j;
            if(m[n-i1-j1]!=1)//判断n-前两位平方和的结果能否由两个整数平方和得到,若能则求这两个整数
                continue;
            for(int k=j;k<s;k++)
            {
                k1=k*k;
                int temp=n-i1-j1-k1;
                if(sqrt(temp)==(int)sqrt(temp))
                {
                    cout<<i<<" "<<j<<" "<<k<<" "<<sqrt(temp)<<endl;
                    return 0;
                }
                
            }
        }
    }
    return 0;
}

Question 9

Password dropped

Archaeologists on Planet X have discovered a number of codes left over from ancient times.
These codes are sequences made up of the seeds of the four plants A, B, C, and D.
After careful analysis, it is found that these password strings should be symmetrical (that is, what we call mirror strings).
Due to the age, many of the seeds have fallen off and may lose their mirror image characteristics.

Your task is:
Given a password string that you see now, calculate how many seeds it has to shed from its original state before it can become the current state.

Enter a line to indicate that the password string you see now (the length is not greater than 1000)
requires a positive integer to indicate at least how many seeds have been dropped.

For example, input:
ABCBA
, the program should output:
0

For another example, input:
ABDCDCBABC
, the program should output:
3

Resource agreement:
peak memory consumption <256M
CPU consumption <1000ms

#include<iostream>
#include<algorithm>
using namespace std;
int dp[1010];//动态规划 求最长公共子序列
int main()
{
    string a,b;
    cin>>a;
    b=a;
    reverse(b.begin(),b.end());
    for(int i=0;i<a.size();i++)
    {
        for(int j=0;j<b.size();j++)
        {
            if(a[i]==b[j])
            {
                dp[j+1]=dp[j+1]+1;
            }
            else
                dp[j+1]=max(dp[j], dp[j+1]);
        }
    }
    cout<<b.size()-dp[b.size()];
    return 0;
}

Tenth question

Maximum ratio

A certain Grand Prix on Planet X has an M-level award. The bonus for each level is a positive integer.
Also, the ratio between two adjacent levels is a fixed value.
That is to say: the bonus numbers of all levels constitute a geometric series. For example:
16,24,36,54
whose ratio is 3/2

Now, we randomly investigate the prize money of some winners.
Please calculate the largest possible ratio based on this.

Input format: The
first line is a number N (0<N<100), which means that the next line contains N positive integers. The
second line contains N positive integers Xi (Xi<1 000 000 000 000), separated by spaces. Each whole number represents the amount of bonus for someone surveyed

Required output:
A score in the form of A/B, requiring A and B to be relatively prime. Represents the largest possible scale factor

The test data ensures that the input format is correct and the maximum ratio exists.

For example, enter:
3
1250 200 32

The program should output:
25/4

For another example, enter:
4
3125 32 32 200

The program should output:
5/2

For another example, enter:
3
549755813888 524288 2

The program should output:
4/1

Analysis: This question was half done before I realized that it was too simple. It is assumed that the answer is 5/2, then after we sort the input data by size, when we compare the two adjacent numbers 3125,200, 125/8 is 5^3/2^3, calculate the largest numerator and denominator Common factor, the result is the answer.

But there is a very pitfall here is that calculating the greatest common factor of the numerator or denominator cannot be divided by toss and turns to get the greatest common factor, anyway, when I did it, I couldn't think about it. Later, I saw other people's solutions, which is the function of gcd1. Emmm probably I didn't have mathematical thinking at the time.

 

#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
vector<long long int> fenmu;
vector<long long int> fenzi;
map<long long int,int> m1;
bool cmp(long long int a,long long int b)
{
    return a<b;
}
void gcd(long long int a,long long int b)
{//得出相邻数字的最简比例
    long long int a1=a,b1=b;
    while(a%b!=0)
    {
        long long int t=b;
        b=a%b;
        a=t;
    }
    fenmu.push_back(a1/b);
    fenzi.push_back(b1/b);
    return;
}
long long int gcd1(long long int a,long long int b)
{//得到目前的最大公约数
    if(a==b)
        return a;
    if(a>b)
        return gcd1(a/b, b);
    else
        return gcd1(a,b/a);
}
int main()
{
    int n;
    cin>>n;
    vector<long long int> a;
    map<long long int,int> m;
    long long int temp;
    int len=0;
    for(int i=0;i<n;i++)
    {
        cin>>temp;
        if(m[temp]!=1)
        {
            m[temp]=1;
            a.push_back(temp);
            len++;
        }
    }
    sort(a.begin(),a.end(),cmp);
    for(int i=0;i<a.size()-1;i++)
    {
        gcd(a[i],a[i+1]);
    }
    long long int temp1=fenmu[0];
    long long int temp2=fenzi[0];
    for(int i=1;i<fenmu.size();i++)
    {
        temp1=gcd1(fenmu[i], temp1);
        temp2=gcd1(fenzi[i], temp2);
    }
    cout<<temp2<<"/"<<temp1<<endl;
    return 0;
}

 

Guess you like

Origin blog.csdn.net/weixin_41242380/article/details/88565398