Blue Bridge Cup Summer Training Question 1

Posted by my_name on Tue, 18 Jan 2022 23:39:04 +0100

Sum of A Series

Skip it.

B k Good Number

Through dfs search, the parameter records the last selected number, then judges the number selected by this bit based on the last selected number, and finally memorizes the number selected by the current status and what the previous number is currently.

#include<bits/stdc++.h>
using namespace std;
const int MOD = 1000000007;
int cnt = 0;
int K,L;
int memo[200][200];
int dfs(int pos,int pre){
    if(pos==L)
        return 1;
    if(pos>L)
        return 0;
    if(memo[pos][pre])return memo[pos][pre];
    int res = 0;
    for(int i=0;i<K;i++){
        if(i==pre+1 || i == pre-1)continue;
        res = (res+dfs(pos+1,i))%MOD;
    }
    return memo[pos][pre] = res;
}

int main(){
    ios::sync_with_stdio(false);
    cin>>K>>L;
    memset(memo,0,sizeof(memo));
    cout<<dfs(0,-1);
}

C 2n Queen Queen Question

The only difference is that the two queens need to be distinguished and cannot be placed in the same place each time, so they can be retrieved as a combination of two positions for each row, but because the interchange of the two positions is obviously an answer, the arrangement of the two positions should be chosen. So each layer of backtracking is arranged in two places.

#include<bits/stdc++.h>
using namespace std;
int n;
int res = 0;

vector<vector<char> >grid(8,vector<char>(8));
bool check(char c,int row,int col) { 
    //On check
    for(int i=row-1;i>=0;i--) {
        if(grid[i][col]==c) 
            return false;
    }//check top left
    for(int i=row-1,j=col-1;i>=0&&j>=0;i--,j--) {
        if(grid[i][j]==c)
            return false;
    }//check top right
    for(int i=row-1,j=col+1;i>=0&&j<n;i--,j++) {
        if(grid[i][j]==c)
            return false;
    }
    return true;
}
//Back in time,'W'means White Queen,'B' means Black Queen
void backtrack(int row){
    if(row==n){
        res++;
        return;
    }
    for(int i=0;i<n;i++){
        for(int j=i+1;j<n;j++){
        //The White Queen's preference
        if(!check('W',row,i))break;
        if(grid[row][i]!='0'&&grid[row][j]!='0'&&check('W',row,i)&&check('B',row,j)){
                grid[row][i] = 'W';grid[row][j] = 'B';
                backtrack(row+1);
                grid[row][i] = grid[row][j] = '1';
            }
            
        }
    }
    for(int i=0;i<n;i++){
        for(int j=i+1;j<n;j++){
            //The Black Queen's preference
        if(!check('B',row,i))break;
        if(grid[row][i]!='0'&&grid[row][j]!='0'&&check('B',row,i)&&check('W',row,j)){
                grid[row][i] = 'B';grid[row][j] = 'W';
                backtrack(row+1);
                grid[row][i] = grid[row][j] = '1';
            }
            
        }
    }
}
int main(){
    // ios::sync_with_stdio(false);
    //Input data ready for backtracking
    cin>>n;
    
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>grid[i][j];
        }
    }
    backtrack(0);
    cout<<res;
}

D Tortoise Rabbit Running Prediction

This question should be used, as long as there is no simultaneous simulation race between the tortoise and the rabbit in the same time period (same layer cycle), note that when the rabbit rests, the tortoise may have reached the end point before all the rest time has been used, so when the tortoise wins, it can divide the distance by the speed of the tortoise directly, which is more accurate. If you want to describe the tortoise's time in a timed manner, you need to enumerate the rabbit's resting time, seconds by seconds, instead of the many seconds that have passed at once. The code here is for timing the tortoise.

#include<bits/stdc++.h>
using namespace std;
int v1,v2,t,s,l;
int main(){
    ios::sync_with_stdio(false);
    cin>>v1>>v2>>t>>s>>l;
    int s1=0,s2=0;
    int tt = 0;
    //Racing simulation of tortoise and rabbit
    for(int i=0;i<l;i++){
        if(s2>=l||s1>=l){
            break;
        }tt++;
        if((s1-s2)<t)
            s1+=v1;
        else{
            //It may not be possible to ask directly here, but if you run directly past the end point in the process, the time is wrong
            if(s2+v2*s<=l){
            tt+=s-1;
            s2=s2+v2*s;}
            else{
                tt--;
                for (int j = 0; j < s; ++j) {
                    if(s2>=l)
                        goto end;
                    s2+=v2;
                    tt++;
                }
            }
            continue;
        }

        s2+=v2;
    }
    end:
    if(s1>s2) {cout<<'R'<<endl;cout<<tt;}

    else if(s1<s2) {cout<<'T'<<endl;cout<<tt;}
    else {cout<<'D'<<endl;cout<<tt;}
}

E Intergalactic Communication

This is a question of finding the next combination of arrays. C++ has a built-in next_ The permutation () template function, of course, can also be implemented by itself, which will be faster, since STL templates need to satisfy all types.

This also counts as a high-frequency interview.

    void nextPermutation(vector<int>& nums) {
        //Find nums[i]<nums[j];
        int i=nums.size()-1;
        for(;i>0;i--){
            if(nums[i-1]<nums[i])
                break;
        }//Direct reverse for maximum permutation
        if(i-1<0){
            reverse(nums.begin(),nums.end());
            return;
        }
        //Swap backwards and forwards for numbers greater than nums[i-1]
        for(int j=nums.size()-1;j>i-1;j--){
            if(nums[i-1]<nums[j]){
                swap(nums[i-1],nums[j]);
                reverse(nums.begin()+i,nums.end());
                return;
            }
        }
    }
  • Problem solving code
#include<bits/stdc++.h>
using namespace std;
int N,M;
    void nextPermutation(vector<int>& nums) {
        //Find nums[i]<nums[j];
        int i=nums.size()-1;
        for(;i>0;i--){
            if(nums[i-1]<nums[i])
                break;
        }//Direct reverse for maximum permutation
        if(i-1<0){
            reverse(nums.begin(),nums.end());
            return;
        }
        //Swap backwards and forwards for numbers greater than nums[i-1]
        for(int j=nums.size()-1;j>i-1;j--){
            if(nums[i-1]<nums[j]){
                swap(nums[i-1],nums[j]);
                reverse(nums.begin()+i,nums.end());
                return;
            }
        }
    }


int main(){
    ios::sync_with_stdio(false);
    cin>>N>>M;
    vector<int> permutation;
    permutation.resize(N);
    for(int i=0;i<N;i++)cin>>permutation[i];
    for (int i = 0; i < M; ++i) {
        nextPermutation(permutation);
    }
    for(int i=0;i<N;i++)
        cout<<permutation[i]<<' ';
    return 0;
}

F Count the number of words (Big man asked, I didn't understand this question)

No, I don't understand the title. Ask for your advice!!!

G Water connection problem

Since the order of water connection has been fixed for you, when the taps are full, which tap will the next one run to? The answer is definitely the one that takes the least time. If you think of the whole process as a continuation at the same time, you only need to add the next time to take the water plus the last time to take the water. Then pick the one that takes the least time from here and add it up, and so on, until everyone has finished taking the water. We just need to see which tap takes the longest time to collect water, which is the ultimate required time.

#include<bits/stdc++.h>
using namespace std;
int n,m;
int findMin(vector<int>&people){
    int min = INT_MAX;
    int pos;
    for(int i=0;i<m;i++){
        if(people[i]<min){
            min = people[i];
            pos = i;
        }
    }
    return pos;
}

int main(){
    ios::sync_with_stdio(false);
    //Solving strategy, first confirm a full team, can not form a full team, we will directly output, the maximum value of water can be.
    //Identify the next continuation position based on the minimum number of people in the team, so go directly to that position and do the same next time until everyone has finished. The largest of these elements is the answer.
    cin>>n>>m;
    vector<int>people(n);
    for(int i=0;i<n;i++)cin>>people[i];
    if(n<=m)
        cout<<*max_element(people.begin(),people.end());
    else{
        int cnt = m;
        while(1){
            if(cnt>=n)
                break;
           int pos = findMin(people);
           people[pos] += people[cnt++];
        }
        cout<<*max_element(people.begin(),people.begin()+m);
    }
    return 0;
}

H Hanoi problem

The Hannotta problem of this topic requires that you can move multiple plates at once, so we can think of it as a Hannotta problem that can be optimized according to M. Finally, the Hannota problem can be considered as several plates according to m, so it is just a few Hannota problems.

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,m;
ll hanoi(int t){
    ll cur = 1;//f(1)
    for(int i=1;i<t;i++){
        cur = 2*cur+1;
    }
    return cur;
}
int main(){
    ios::sync_with_stdio(false);
    cin>>n>>m;
    int q;
    if(n%m)
        q = n/m + 1;
    else
        q = n/m;
    cout<<hanoi(q);
    return 0;
}

Topics: Algorithm