2021 RoboCom world robot developer competition - undergraduate group (Preliminary)

Keywords: Algorithm

catalogue

Write in front

7-1 understand everything

subject

Input format:

Output format:

Input example:

Output example:

meaning of the title

thinking

code

7-2 Finnish wooden chess

subject

Input format:

Output format:

Input example:

Output example:

meaning of the title

thinking

code

7-3 play strange upgrade

subject

Input format:

Output format:

Input example:

Output example:

meaning of the title

thinking

code

7-4 epidemic prevention and control

subject

Input format:

Output format:

Input example:

Output example:

meaning of the title

thinking

code

reflect

Write in front

        This is a new competition. I got four questions last Saturday. Although I was promoted to the later competition, the situation is not ideal. I think it's a little dangerous to enter the final. I think it's good to fill these four questions. It's just time to reflect on myself.

        Although it was said that this was the L2 difficulty of the ladder race, I didn't feel good when I took the exam. I only got the first question A and thought it should be L3 difficulty. However, I found that I didn't find L3 difficulty in the later supplementary questions, which was probably between L2 and L3. On the whole, the first question was A, the second question was 17 points, I don't know where I made A mistake, and there was A point in the later supplementary question (many people didn't have A). The third question was graph theory. I read the wrong question at that time, only 16 points, and running dij was not 16 points. The fourth question was violent dfs, which was only 1 point, which was outrageous. Some points were wa... The bosses taught me how to write.

7-1 understand everything

subject

         As we all know, many words on the Internet are not easy to say directly, but some fuzzy pictures can still let netizens understand what you are saying. However, we still have to punch hard at this kind of speech, so please implement a simple matching algorithm.

         Now we have collected some characteristic data of the original image   N   It is composed of non negative integers less than 255. It is assumed that for a given number of sheets, it is composed of   Mi​   The characteristic data of a new graph composed of non negative integers less than 255, and each data can be calculated from the average value of any four different data in the original graph, then the new graph is called a similar picture of the original graph. For the given data, please judge whether it is a similar picture.

         Note that different data does not mean different data values, but the same data cannot be taken multiple times. For two data with the same value, if given twice, it can be taken twice.

Input format:

         The first line of input is two integers   N,K   (1 ≤   N   ≤ 50, 1 ≤   K   ≤ 200), indicating the number of characteristic data of the collected original drawing and the number of new drawings.         

         Next behavior   N   A non negative integer less than 255 representing the characteristic data of the original drawing.

         final   K   Rows, the first number in each row is   Mi​   (1 ≤   Mi​   ≤ 200), indicating the number of characteristic data of the new graph. And then   Mi​   A non negative integer less than 255 representing the characteristic data of the new graph.

Output format:

         For each new picture, if it is a similar picture, output Yes in one line, otherwise output No.

Input example:

5 3
4 8 12 20 40
3 11 16 19
3 12 16 19
10 11 11 11 11 11 11 11 11 11 11

Output example:

Yes
No
Yes

meaning of the title

        Given n numbers, n is less than or equal to 50, there are k queries, and there are several numbers x in each query. Ask whether 4*x can be represented by 4 numbers with different subscripts in the first n numbers

thinking

        A simple topic was written in the exam, which make complaints about the state of mind (Tucao).

        Because n is not big, we can use dfs to simulate all situations. Roughly, choose 4 out of 50. C(50,4) has little time complexity. Then save it to indicate that it can form this number. Finally, judge whether it is OK when asking

code

const int N = 51;
int n,m,a[N],k,x;
unordered_map<int,int> mp;
inline void dfs(int x,int num,int sum)
{
    if (num==4) 
    {
        mp[sum]=1;
        return;
    }
    for (int i=x+1;i<=n+num-3;i++)
        dfs(i,num+1,sum+a[i]);
}
inline void Case_Test()
{
    cin>>n>>m;
    for (int i=1;i<=n;i++)
        cin>>a[i];
    dfs(0,0,0);
    while (m--)
    {
        cin>>k;
        bool boo=true;
        for (int i=1;i<=k;i++)
        {
            cin>>x;
            if (mp[x*4]) continue;
            boo=false;
        }
        if (boo) cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
}

7-2 Finnish wooden chess

subject

         Finnish wooden chess (M ö lkky, also known as Finnish wooden pole) is a sport originated from Finland. Zhezhe transformed this sport into a single version of cyberpunk. Now there are many people on the court at the beginning   N   The small wooden chess set up by the root (each marked with a non negative integer), zhe zhe throws a big wooden chess to knock down these small wooden chess to obtain points. The scoring rules are as follows:

  • If you knock down only one wooden chess, you will get the score on the wooden chess.
  • If you knock down 2 or more pieces of wooden chess, you can only knock down the score of the number of pieces. (for example, if you knock down 5, you will get 5 points.)

         Zhe Zhe is standing there   (0,0)   On the spot, there are several small wooden chess pieces around   (Xi, Yi), coordinates are integers. Every time zhe zhe can throw a big wooden chess in one direction, the big wooden chess will knock down the one closest to zhe Zhe in this direction   k   A small wooden chess. Zhe Zhe's game level is very high, so this   k   Can be controlled freely.

         How many points can zhe zhe get at most and how many times should he throw a big wooden chess when he gets the most points?

         There is a big difference between the rules and the real rules. Please follow the rules of the international morky organization when playing in the real world

Input format:

         The first line of input is a positive integer   N   (1 ≤   N   ≤  ), indicating that there was a problem in the field at the beginning   N   A wooden chess.

         next   N   Rows, 3 integers per row   Xi, Yi and PI respectively indicate that the wooden chess is placed on the   (Xi, Yi), the score on wooden chess is   Pi​. The coordinates are in the range of 32-bit integers, and the fraction is a positive integer less than or equal to 1000.

         ensure   (0,0)   There is no wooden chess, and there is no overlapping of wooden chess.

Output format:

         Output two numbers in one line, indicating the maximum score and the minimum number of times to throw a big wooden chess to obtain the maximum score.

Input example:

11
1 2 2
2 4 3
3 6 4
-1 2 2
-2 4 3
-3 6 4
-1 -2 1
-2 -4 1
-3 -6 1
-4 -8 2
2 -1 999

Output example:

1022 9

meaning of the title

        Given n numbers, each number has a Pi score at the position of (Xi,Yi). Each time we stand at the origin (0,0) and throw a big wooden chess in one direction, we can make it stop at any place, ask what the maximum score is, and then ask how many times we need to throw at least.

        There are two scoring rules:         

  • If you knock down only one wooden chess, you will get the score on the wooden chess.
  • If you knock down 2 or more pieces of wooden chess, you can only knock down the score of the number of pieces. (for example, if you knock down 5, you will get 5 points.)

thinking

        At the beginning of the topic, I wrote non negative integers. I also took 0 into account. For example, if there is only 0 in one direction, there is no need to throw it. Then if there is {1,0,0,0,1} and so on... But it doesn't have any impact in terms of reason, and there should be more points.

        Obviously, this problem needs to be divided into many parts. According to the slope, each slope has a vector container to store the position and Pi score value, but this is disordered, so we need to sort each vector container. Then start sweeping. If you encounter a continuous 1, you don't need to throw it again. According to this idea, it can be simplified as follows:

        Obviously, ans1 is the sum of Pi, because the problem requirement is the largest, then ans2 first is n (n objects are thrown n times). If there is a continuous 1 for scanning, then ans2 --, because it can be less once.

        For each slope k, I use a map to store it. It is the first item. In fact, I can use pair to store the numerator and denominator, because there may be a precision problem (but there should be no problem with this problem. Someone wrote that or wa dropped a point).

        Note that the same slope has two directions, but one is from 0,1,2,...,+oo and the other is from 0,-1,-2,...,-oo. The sorting method is different. I use two vector s to distinguish.

code

const int N = 1e6+7;
vector<pair<ll,ll> > v3,v4;
vector<pair<ll,ll> > v1[N],v2[N];
unordered_map<double,int> mp1,mp2;
int cnt1,cnt2,n,w;
double k,x,y;
ll ans1,ans2;
inline void Case_Test()
{
    cin>>n;
    ans2=n;
    for (int i=1;i<=n;i++)
    {
        cin>>x>>y>>w;
        ans1+=w;
        if (x==0)
        {
             if (y>0) v3.push_back({y,w});
             else v4.push_back({-y,w});
             continue;
        }
        k=y*300/x;
        if (y>0)
        {
            if (!mp1[k]) mp1[k]=++cnt1;
            v1[mp1[k]].push_back({y,w});
        }
        else
        {
            if (!mp2[k]) mp2[k]=++cnt2;
            v2[mp2[k]].push_back({-y,w});
        }
    }
    for (int i=1;i<=cnt1;i++)
    {
        sort(v1[i].begin(),v1[i].end());
        for (int j=1;j<v1[i].size();j++)
            if (v1[i][j].second==1&&v1[i][j-1].second==1) ans2--;
    }
    for (int i=1;i<=cnt2;i++)
    {
        sort(v2[i].begin(),v2[i].end());
        for (int j=1;j<v2[i].size();j++)
            if (v2[i][j].second==1&&v2[i][j-1].second==1) ans2--;
    }
    for (int i=1;i<v3.size();i++) 
        if (v3[i].second==1&&v3[i-1].second==1) ans2--;
    for (int i=1;i<v4.size();i++)
        if (v4[i].second==1&&v4[i-1].second==1) ans2--;
    cout<<ans1<<" "<<ans2;
}

7-3 play strange upgrade

subject

         Many games have a strange upgrade link. Players need to defeat a series of monsters to win achievements and badges. Here we consider a simple upgrade game. The rules of the game are given   N   A map of fortresses. There are roads between fortresses, and each road is guarded by a monster. The monster itself has energy and the weapons in its hand are valuable. The energy needed to defeat the monster is equal to the energy of the monster itself, and once the monster is defeated, the weapons belong to the player - of course, the higher the value of the captured weapons, the happier the player will be.

You have two tasks:

  • Help the player to determine the most cost-effective airborne location, that is, airborne to a fortress in the map, so that the player can start from this airborne point and need the least energy to capture the fortress that is most difficult to capture (i.e. consumes the most energy);
  • Starting from this airborne point, help players find the most energy-saving path to conquer any fortress they want to conquer. If this path is not unique, choose the solution with the highest total value of weapons captured along the way, and ensure that this solution is unique.

Input format:

         The first line of input gives two positive integers   N   (≤ 1000) and   M. Among them   N   Is the total number of fortresses, M   Is the total number of monsters. For simplicity, we will change the fortress from 1 to 2   N   Number. subsequently   M   OK, No   i   Line gives the second line   i   Information of monsters in the following format:

B1 B2 Monster Energy Weapon value

         among   B1   and   B2   It is the fortress number at both ends of the monster guarded road. The problem is to ensure that only one monster is guarded between each pair of forts, and   Monster Energy   and   Weapon value   Are positive integers no more than 100.

         Followed by a positive integer   K (≤ N) and what players want to conquer   K   The number of the target fortress.

Output format:

         First, output the fortress number of player airborne in one line   B0. If there are multiple possibilities, the one with the smallest number is output.

         Then each fortress that the player wants to conquer in turn   B   Recommend the most energy-saving attack path, and list the energy value to be consumed and the total value of weapons captured along the way. Note that if the most labor-saving path is not unique, select the solution with the highest total value of weapons captured along the way. The format is:

B0->Via fortress 1->...->B
 Total energy cost total weapon value

Input example:

6 12
1 2 10 5
2 3 16 20
3 1 4 2
2 4 20 22
4 5 2 2
5 3 12 6
4 6 8 5
6 5 10 5
6 1 20 25
1 5 8 5
2 5 2 1
2 6 8 5
4
2 3 6 5

Output example:

5
5->2
2 1
5->1->3
12 7
5->4->6
10 7
5
0 0

meaning of the title

        Let's look at the problem... Graph theory problem

thinking

        Run Floyd again to get the point s we selected, and then run again to get the smallest path and the largest weapon. Pay attention to how Floyd saves the path

code

const int N = 1007;
int u,v,n,m,g[N][N],w[N][N],temp,s,x;
int path[N][N],dist[N][N];
inline void floyd()
{
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                if (dist[i][k]+dist[k][j]<dist[i][j])
                    dist[i][j]=dist[i][k]+dist[k][j],path[i][j]=k,g[i][j]=g[i][k]+g[k][j];
                if (dist[i][k]+dist[k][j]==dist[i][j]&&g[i][k]+g[k][j]>g[i][j])
                    path[i][j]=k,g[i][j]=g[i][k]+g[k][j];
            }
}
inline void output(int i,int j)
{
    if(i==j) return;
    if(path[i][j]==0) cout<<"->"<<j;
    else
    {
        output(i,path[i][j]);
        output(path[i][j],j);
    }
}

inline void Case_Test()
{
    cin>>n>>m;
    memset(w,0x7f/3,sizeof(w));
    memset(g,0,sizeof(g));
    memset(dist,0x7f/3,sizeof(dist));
    for (int i=1;i<=n;i++) w[i][i]=g[i][i]=0;
    for (int i=1;i<=m;i++)
    {
        int x,y;
        cin>>u>>v>>x>>y;
        dist[u][v]=dist[v][u]=x;
        w[v][u]=w[u][v]=x;
        g[v][u]=g[u][v]=y;
    }
    for (int k=1;k<=n;k++)
        for (int i=1;i<=n;i++)
            for (int j=1;j<=n;j++)
                if (w[i][j]>w[i][k]+w[k][j])
                    w[i][j]=w[i][k]+w[k][j];
    /*for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=n;j++)
            cout<<w[i][j]<<" ";
        cout<<endl;
    }*/
    temp=inf;
    for (int i=1;i<=n;i++)
    {
        int tmp=-1;
        for (int j=1;j<=n;j++)
        {
            if (i==j) continue;
            if (w[i][j]>tmp) tmp=w[i][j];
        }
        if (tmp<temp) temp=tmp,s=i;
    }
    cout<<s<<endl;
    floyd();
    cin>>m;
    while (m--)
    {
        cin>>x;
        cout<<s;
        output(s,x);
        if (s==x) cout<<"\n0 0\n";
        else
        cout<<endl<<dist[s][x]<<" "<<g[s][x]<<endl;
    }
}

ps: I don't know why there is an error when s==x... Not 0, 0

7-4 epidemic prevention and control

subject

         The epidemic situation is not over yet. We should strictly prevent the recurrence of the epidemic situation. In order to do a good job in epidemic prevention and control, regional risk levels have been set in China, and personnel in medium and high-risk areas have been restricted from moving and isolated at home.

         In order to study the impact of epidemic prevention and control on cross regional transportation, it is assumed that there are   N   An airport, M   Every day, a new prevention and control area will be added to each route. A prevention and control area will cause an airport to fail to operate normally, and the route will naturally fail to operate normally. There will be accidents every day   Qi​   For passengers from   Xi​   Airport bound   Yi​   Airport, please calculate how many passengers will be affected and unable to complete the trip.

         As long as passengers can go directly or through several transfers, and the departure and arrival airports of all routes are in normal operation, they are deemed to be able to complete the journey.

Input format:

         The first line of input is three integers   N,M,D   (1≤N≤5 × 104,   1≤M≤2 × 105,   1 ≤ D ≤ 103), indicating the number of airports, routes and days of new prevention and control areas.

         Next, first   M   Lines, each line gives two numbers separated by spaces   A   and   B. Indicates that the number is   A   and   B   There is a route between airports. The route is two-way, and the airport number is from 1 to   N.

         And then   D   Block input, two integers separated by spaces in the first line of each block input   C   and   Q   (1 ≤ Q ≤ 103), indicating that the new airport number is   C   The city is a prevention and control area. Today there are   Q   Segment itinerary. The data ensure that the new city must not be a prevention and control area before.

         Next   Q   Lines, each line is two numbers separated by spaces   X   and   Y. Indicates that the number is   X   and   Y   A trip to the airport. The trip may include cities that have previously become prevention and control areas.

Output format:

         For daily inquiries, please output in one line the number of itineraries that cannot be made on the day after a new prevention and control area is added.

Input example:

5 5 3
1 2
1 3
1 5
2 5
3 4
4 3
1 3
1 4
2 3
5 3
3 4
2 3
3 5
1 3
2 3
2 5
3 4

Output example:

1
2
3

meaning of the title

        Give an undirected graph, D times, turn off the current node in turn. Each time, there are several queries to ask you whether X and y are still connected.

thinking

        Use the idea of joint search set.

        This question really didn't think of the reverse. Read all the input and save it, and start to join in the reverse. In this way, it only needs to be done once. After processing the current, go to join once to see if it can be added, and so on.

        At the beginning, pay attention to adding all the edges that meet the conditions in any case.

code

const int N =2e5+7;
int father[N];
inline int find(int x)
{
    return father[x]==x?x:father[x]=find(father[x]);
}
struct node
{
    int to,next,x;
}edge[N<<1];
int head[N],cnt;
vector<int> que,ans;
inline void add(int x,int to)
{
    edge[++cnt].next=head[x];
    edge[cnt].x=x;
    edge[cnt].to=to;
    head[x]=cnt;
}
int n,m,d,x,y,c,q,fx,fy;
vector<pair<int,int> > v[1007];
bool vis[N];
inline void Case_Test()
{
    cin>>n>>m>>d;
    for (int i=1;i<=n;i++) father[i]=i;
    for (int i=1;i<=m;i++)
    {
        cin>>x>>y;
        add(x,y);add(y,x);
    }
    for (int i=1;i<=d;i++)
    {
        cin>>c>>q;
        que.push_back(c);
        vis[c]=1;
        for (int j=1;j<=q;j++)
        {
            cin>>x>>y;
            v[i].push_back({x,y});
        }
    }
    for (int i=1;i<=cnt;i++)
    {
        x=edge[i].x;
        y=edge[i].to;
        //cout<<i<<" "<<x<<" "<<y<<endl;
        if (!vis[x]&&!vis[y])
        {
            fx=find(x);fy=find(y);
            if (fx!=fy) father[fy]=fx;
        }
    }
    for (int i=d;i>=1;i--)
    {
        c=que[i-1];q=v[i].size();
        cnt=0;
        for (auto p:v[i])
        {
            x=p.first;y=p.second;
            fx=find(x);fy=find(y);
            if (fx!=fy) cnt++;
        }
        ans.push_back(cnt);
        x=c;
        for (int j=head[x];j;j=edge[j].next)
        {
            y=edge[j].to;
            if (vis[y]) continue;
            fx=find(x);fy=find(y);
            if (fx!=fy) father[fy]=fx;
        }
        vis[c]=0;
    }
    for (int i=ans.size()-1;i>=0;i--)
        cout<<ans[i]<<endl;
}

reflect

        Take a good test next time and try to get into the final.

        These questions remind me that sometimes thinking in reverse can simplify the problem, and how Floyd saves the path. There are still too few problems in graph theory. Because there is a big man in the team, I have not been responsible for graph theory

Posted by fisel on Wed, 13 Oct 2021 08:45:03 -0700