2021 January Contest Bronze problem solution

Keywords: USACO

T1 Uddered but not Herd

Topic description

A little-known fact is that cows have their own words: "Niu Wen". Niu Wen consists of 26 letters' a 'to' z ', but when the cow speaks Niu Wen, it may be different from the familiar' abcdefghijklmnopqrstuvwxyz '. She will arrange the letters in a certain order.
To pass the time, Bessie the cow was humming the cow alphabet song repeatedly, and Farmer John wondered how many times she sang it.

Given a string composed of lowercase letters, calculate the letters that Bessie sang for Farmer John, and calculate that Bessie sang the complete niuwen alphabet song at least several times, so that farmer John can hear the given string. Farmer John doesn't always pay attention to what Bessie sings, so he may miss some letters that Bessie sings. The given string contains only the letters he remembers he hears.

Input format (read from terminal / standard input):

The first line of input contains the order of the bovine alphabet of 26 lowercase letters' a 'to' z '. The next line contains a string of lowercase letters for Farmer John to hear Bessie sing. The length of the string is not less than 1 and not more than 1000.

Output format (output to terminal / standard output):

Output the minimum number of complete niuwen alphabet songs sung by Bessie.

Input example:

abcdefghijklmnopqrstuvwxyz
mood

Output example:

3

Example explanation

In this example, the Niu alphabet is aligned with the daily alphabet.
Bessie sang the cow alphabet song at least three times. It's possible that Bessie only sang the cow Alphabet Song three times, and Farmer John heard the following capitalized letters.
abcdefghijklMnOpqrstuvwxyz
abcdefghijklmnOpqrstuvwxyz
abcDefghijklmnopqrstuvwxyz

Nature of test point:

In test points 2-5, the Niu alphabet is the same as the daily alphabet.
There are no additional restrictions on test points 6-10.

I try to write the answer to this question directly with a formula, but I can't write it at all.

OK, so the idea of this question is very obvious, that is, if the character of my current digit is in the front position of the alphabet for the previous character, it is obviously illegal. At the same time, it should be noted that if there are two consecutive characters now, it must have been sung twice, there is no doubt.

Konjac die Code:

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
template <typename T>inline void read(T& t){
    t=0; register char ch=getchar();
    while(!('0'<=ch&&ch<='9')){if(ch=='-') t=-1;ch=getchar();}
    while(('0'<=ch&&ch<='9')){t=((t<<1)+(t<<3))+ch-'0'; ch=getchar();}
}
template <typename T,typename... Args> inline void read(T& t, Args&... args){
    read(t);read(args...);
}
template <typename T>inline void write(T x){
    if(x<0) putchar('-'),x=~(x-1); int s[40],top=0;
    while(x) s[++top]=x%10,x/=10; if(!top) s[++top]=0;
    while(top) putchar(s[top--]+'0');
}
string st;
bool later(char ch1,char ch2){
    //Wrote a function to determine whether ch1 is after ch2
    //At the same time, if ch1 is exactly equal to ch2, it means that I read a word twice, which directly accumulates the answers
    if(ch1==ch2) return 1;
    for(int i=0;i<st.size();++i){
        if(st[i]==ch1) return 0;
        if(st[i]==ch2) return 1;
    }
    return 0; //It won't be this time
}
int ans;
string st1;
int main(){
    cin>>st>>st1;
    char lch=st1[0];
    for(int i=1;i<st1.size();++i){
        if(later(lch,st1[i])) ans++;
        lch=st1[i];
    }
    cout<<ans+1<<endl;
    return 0;
}

T2 Even More Odd Photos

Topic description

Farmer John is trying to photograph his N cows again (2 ≤ N ≤ 1000).
Each cow has an integer "breed number" in the range of 1... 100. Farmer John has a very strange idea for his photos: he wants to divide all cows into disjoint groups (in other words, divide each cow into exactly one group) and arrange these groups in a row so that the sum of breed numbers of cows in the first group is even, the sum of numbers of cows in the second group is odd, and so on.
What is the maximum number of groups that Farmer John can be divided into?

Input format (read from terminal / standard input):

The first line of input contains n. The next line contains an integer separated by N spaces, which is the breed number of N cows.

Output format (output to terminal / standard output):

Output the maximum number of groups in Farmer John's photos. It can be proved that there is at least one satisfactory grouping scheme.

Input example 1:

7
1 3 5 7 9 11 13

Output example 1:

3

Example explanation 1

In this example, the following is a scheme divided into three groups with the maximum number of groups. Divide 1 and 3 into the first group, 5, 7 and 9 into the second group, and 11 and 13 into the third group.

Input example 2:

7
11 2 17 13 1 15 3

Output example 2:

5

Example explanation 3:

In this example, the following is a scheme divided into five groups. Divide 2 into group 1, 11 into group 2, 13 and 1 into group 3, 15 into group 4, and 17 and 3 into group 5.

Problem solving ideas:

It feels like a big simulation. I've thought about it for a long time. I won't talk about the details. See die code. Note: the standard answer given by USACO seems that the complexity of die code is higher than mine:

Forget it, let's talk about it a little to avoid forgetting how to do it in the future.

First of all, you will find that the number size is useless, but its parity will change a lot.

ok, first of all, there is an obvious greedy idea, that is, if I need an odd number now, I must be the last odd number, not the last even number plus an odd number, because obviously, this even number can be placed in the back one to create more value.

According to this idea, I will now count the even number and the odd number.
Then now judge whether there are many even numbers or many odd numbers.
From a simple start, if there are many even numbers, put even odd numbers and even odd numbers, and you will find that after the even number after the last odd number, any more even numbers can only be superimposed to the front, so you can't create a new odd number. Therefore, the answer is relatively simple, that is, the odd number * 2 + 1. This is a relatively simple case.
If the number is the same, the answer is obviously the sum of the two numbers \ (\ text{n} \)
From simple to complex, if it is odd now, there are many.
As an aside, it's actually easy to understand why a large number of odd numbers are more complex. That is, when there are more odd numbers, my two odd numbers can be combined into even numbers. Putting an odd number elsewhere will change the parity, so it shows that a large number of odd numbers is more complex.
OK, let's get back to the point. What if there are many odd numbers. You might as well consume all the even numbers that can be consumed (it's necessary sooner or later anyway).
My answer now is \ (ans\times 2 \). Then, I still have odd numbers minus even numbers, odd numbers (it seems very winding).
Suppose I have \ (\ text{pos} \) odd numbers left now. It seems to be a rule. Make a table.

In fact, there is a good-looking table, but I can't write \ (\ LaTeX \), just.

\( \begin{matrix} pos \Delta ans\\ 1 \ \ -1\\ 2 \ \quad\ \ 1\\ 3 \ \quad\ \ 2\\ 4 \ \quad\ \ 1\\ 5 \ \quad\ \ 3\\ 6 \ \quad\ \ 4\\ 7 \ \quad\ \ 3\\ \end{matrix} \)

OK, it's not difficult to find the law now. The law doesn't need to be written in \ (\ LaTeX \)

Konjac die Code:

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
template <typename T>inline void read(T& t){
    t=0; register char ch=getchar();
    while(!('0'<=ch&&ch<='9')){if(ch=='-') t=-1;ch=getchar();}
    while(('0'<=ch&&ch<='9')){t=((t<<1)+(t<<3))+ch-'0'; ch=getchar();}
}
template <typename T,typename... Args> inline void read(T& t, Args&... args){
    read(t);read(args...);
}
template <typename T>inline void write(T x){
    if(x<0) putchar('-'),x=~(x-1); int s[40],top=0;
    while(x) s[++top]=x%10,x/=10; if(!top) s[++top]=0;
    while(top) putchar(s[top--]+'0');
}
int n;
int odd,even,ans;
int main(){
    cin>>n;
    while(n--){
        int t;
        read(t);
        if(t%2==0) even++;
        else odd++;
    }
    if(odd==even){
        cout<<odd<<endl;
        return 0;
    }
    //OK, now that you know the process, simulate it
    //Now let's construct that the first group is even and the second group is odd. That's always the case. Let's see whether it's even or odd
    if(odd>even){
        //If there are many odd numbers, add up the even numbers first
        ans=even*2;
        //even odd numbers to contribute
        odd=odd-even;
        if(odd%3==1)
            cout<<(odd/3)*2-1+ans<<endl;
        else 
            if(odd%3==0)
                cout<<(odd/3)*2+ans<<endl;
            else
                cout<<(odd/3)*2+1+ans<<endl;
        return 0;
        //OK, the next one should be even and then odd
        //Make a watch and have a look
        //Another is that if there is an odd number left, but this one requires an even number, it is difficult to do. It will break the balance wherever it is placed. What should we do.
        //Odd number, so the only way to think of is to group two less, and there must be more left in your hand now
        /*
        Two less groups, two less groups are odd and even
        These two can only be:
        Even: two odd numbers or an even number
        Odd: single odd
        Then you can remove the odd number and replace it with an odd number in front of the even number
        One left,
        What about two left?
        Two left just make an even number, and three left?
        There are three left, just two, and it won't cause a problem
        There are four left. If there are four, it must be 3 + 1, so there are only two
        Five, 2 + 1 + 2 first
        Six are 2 + 1 + 2 + 1
        Seven are 2 + 1 + 3 + 1
        So the answer has to be divided by three
        Divide by 3 and see the remainder after dividing by 3
        For example, if 7 / 3 is more than 1, the answer is (7 / 3) * 2
        Four (4 / 3) * 2
        What about the remaining 2
        (5/3)*2+1
        Remaining 0 (6 / 3) * 2
        */
    }else{
        //The rest is that I now have more even numbers than odd numbers, so it's simpler,
        /*
        Let me start with an even number
        Another odd number
        So repeatedly, until there is no odd number
        Then I'm on all even numbers now
        How many numbers have been added (odd number * 2 + 1)
        */
       cout<<odd*2+1<<endl;
    }
    return 0;
}

T3 Just Stalling

Topic description

Farmer John has N cows (1 ≤ N ≤ 20) with a height of a1... aN. His cowshed has N cowsheds, and the height limits are b1... bN respectively (for example, if b5=17, a cow with a height of no more than 17 can live in cowshed 5). How many different ways does farmer John arrange his cows so that each cow lives in a different barn and the height limit of each barn is met?

Input format (read from terminal / standard input):

The first line of input contains N. The second line contains N space separated integers a1,a2,..., aN. The third line contains N space separated integers b1,b2,..., bN. All heights and height limits are within the range [1109].

Output format (output to terminal / standard output):

Output the number of methods that Farmer John can arrange each cow in different cowshed so that the height limit of each cowshed can be met. Note that the number of outputs may need to be of 64 bit integer type, such as long in C + +.

Input example:

4
1 2 3 4
2 4 3 4

Output example:

8
In this example, we cannot arrange the third cow in the first barn because 3 = A3 > B1 = 2. Similarly, we cannot arrange the fourth cow in the first or third barn. One arrangement that meets the height limit is to arrange cow 1 to cowshed 1, cow 2 to cowshed 2, cow 3 to cowshed 3 and cow 4 to cowshed 4.

Nature of test point:

Test points 1-5 meet N ≤ 8.
Test points 6-12 have no additional restrictions.

Problem solving ideas

In fact, at the beginning, I couldn't do this problem at all, because I omitted the important condition of height. I directly simulated the two edges in the bipartite graph with height, and then I always wanted to optimize the method of violence. Until I suddenly thought that no matter how optimized my method is, I must search each method, and then the answer is within \ (\ text{long long} \), so it's no wonder it doesn't explode.

Then, I took a little look at the answer and felt that the practice was very clever.

It is mainly to forcibly construct the state that the multiplication principle can be applied, and then calculate.

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
template <typename T>inline void read(T& t){
    t=0; register char ch=getchar();
    while(!('0'<=ch&&ch<='9')){if(ch=='-') t=-1;ch=getchar();}
    while(('0'<=ch&&ch<='9')){t=((t<<1)+(t<<3))+ch-'0'; ch=getchar();}
}
template <typename T,typename... Args> inline void read(T& t, Args&... args){
    read(t);read(args...);
}
template <typename T>inline void write(T x){
    if(x<0) putchar('-'),x=~(x-1); int s[40],top=0;
    while(x) s[++top]=x%10,x/=10; if(!top) s[++top]=0;
    while(top) putchar(s[top--]+'0');
}
int n,a[114],b[514];
bool cmp(const int &infoa,const int &infob){
    return infoa>infob;
}
long long ans=1;
int main(){
    cin>>n;
    for(int i=1;i<=n;++i) cin>>a[i];
    for(int i=1;i<=n;++i) cin>>b[i];
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;++i){
        int sum=0;
        /*
        Now rank the cows in descending order.
        Then think about it one by one
        Mainly want to use the principle of multiplication.
        How? That means, I know now
        There are sum positions in the ith position.
        At this time, I will think that the place in the i-1 position must be in the middle of these sum things
        In fact, I have only sum-i+1 methods to choose from. Is this method right?
        */
        for(int j=1;j<=n;++j)
            if(b[j]>=a[i]) sum++;
        ans*=(sum-i+1);
    }
    cout<<ans<<endl;
    return 0;
}

Finish scattering flowers!

Posted by skizzay on Fri, 03 Dec 2021 10:43:13 -0800