Guangzhou University ACM2021 Week 11 training 2021.05.16

Posted by dipenmistry on Fri, 11 Feb 2022 13:32:58 +0100

Guangzhou University ACM2021 Week 11 training

Gossip: I haven't played weekly games for a long time (actually not). I went online for three hours in five hours. On the whole, the first five questions are very simple, but they haven't been handled well in the details, which is a test of my mentality. Finally, question a4. After reading the fifth question, you will have something to run away from. However, it is also a violent enumeration question, which is just a little bit compressed.

A - transaction Gym - 102890I

meaning of the title


The general meaning is to buy three books (read into n books at the beginning). The price is given and can be combined to pay according to needs. There is a discount here, that is, reduce 100 from 500.

Problem solution

Since the title says 500 minus 100, try to gather more than 500 groups for a long time. We can sort them first, and then record the total price in a group from small to large. When the sum is greater than or equal to 500, we can divide them into a group. Because there are only three books here, it is very simple. Even enumeration can be used. The method here should be used for n.

code

using namespace std;
const int N=1e5;
int a[N];
int main()
{
    //IOS
    int d;
    int cnt=0;
    while(cin>>d){
        a[cnt++]=d;
    }
    sort(a,a+cnt);
    ll ans=0;
    int i=0;
    ll t=0;
    for(;i<cnt&&a[i]<500;i++){
        t+=a[i];
        if(t>=500){
            ans+=(t-100);t=0;
        }
    }
    if(t>0){
        ans+=t;
    }
    for(;i<cnt;i++)ans+=(a[i]-100);
    cout<<ans<<'\n';
    return 0;
}

B - Triangle Gym - 102890C

meaning of the title


The number of triangles is required. There was originally a big triangle, but now it is cutting n lines from the bottom, and then cutting k lines parallel to the ground. How many different triangles can be included at this time. There are t sets of samples in total.

Problem solution

First of all, it is easy to find that one vertex of the triangle is determined. If you cut k knives in parallel, you have to traverse the bottom edge when counting, so here are k+1 bottom edges, and the situation of each side is the same, that is, count one of them and multiply by k+1.
For each group of edges, the N cutter is divided into n+1 small triangles, and several adjacent small triangles can form a large triangle. Therefore, starting from the size of the triangle, there should be n+1, N, n-1, ~ ~, which is added to n-p=0, that is, the largest triangle, i.e. n+1. Obviously, it's the arithmetic sequence 1 added to n+1. The answer is multiplied by k+1.
Here wa is a lot of times, because I noticed that the answer should be mod1e7, and I put / 2 at the end of the arithmetic sequence to calculate, which is completely icing on the cake. Because the result of the arithmetic sequence (it is easy to find that it must be an odd number multiplied by an even number) takes the module, its parity changes. If you go to / 2 later, there will be an error. You should take the module honestly / 2.

code

using namespace std;
const int N=1e5;
const ll mod=1000000007;
int a[N];
int main()
{
    //IOS
    int t;cin>>t;
    while(t--)
    {
        ll n,k;
        cin>>k>>n;
        ll ans=(((k+1)*(k+2)/2)%mod*(n+1))%mod;
        cout<<ans<<'\n';
    }
    return 0;
}

C - formula AtCoder - arc061_a

meaning of the title

Give you a string s containing only 1 ~ 9, and the length of the string is less than 10. You can insert "+" between any two letters to make it a legal formula. You can not insert a "+" sign and ask you the sum of all legal formulas

Problem solution

The string is very short. You can add or not add a plus sign everywhere. When enumerating binary compression.

code

using namespace std;
const int N=122;
const ll mod=1000000007;
ll dp[12][12];
int main()
{
    //IOS
    string s;cin>>s;
    int len=s.length();
    ll ans=0;
    ll now=0;
    for(int i=0;i<(1<<len-1);i++){
        now=0;
        for(int j=0;j<len;j++){
            now=now*10+s[j]-'0';
            if(j==len-1||(1<<j)&i){
                ans+=now;
                now=0;
            }
        }
    }
    cout<<ans<<'\n';
    return 0;
}

D - communication network Gym - 102890D

meaning of the title


It is required to translate the string and give a maximum length. Exceeding this length is illegal.
As for the string format, the number plus letter indicates how many letters there are. There are only lowercase letters, and numbers can be omitted when there is one.

Problem solution

There's nothing to say. Just simulate.

code

using namespace std;
const int N=1e5;
const ll mod=1000000007;
int a[N];
int main()
{
    //IOS
    int t;cin>>t;
    while(t--){
        string s;cin>>s;
        int maxn;cin>>maxn;
        string ans;
        int len=s.length();
        int p=1;
        bool yes=1;
        ll all=0;
        for(int i=0;i<len;){
            if(s[i]>='a'&&s[i]<='z'){
                ans+=s[i];
                all++;
                i++;
            }
            else {
                int j=i;
                string temp;
                temp+=s[j++];
                while(s[j]>='0'&&s[j]<='9')temp+=s[j],j++;
                ll o=atoi(temp.c_str());
                all+=o;
                if(all>maxn){yes=0;break;}
                while(o--)ans+=s[j];
                i=j+1;
            }
            if(yes==0)break;
        }
        if(all>maxn||(s[len-1]>='0'&&s[len-1]<='9'))yes=0;
        if(yes==0)cout<<"unfeasible\n";
        else if(yes==1)cout<<ans<<'\n';
    }
    return 0;
}

E - calculate word Gym - 102890L

meaning of the title


A rule of "substring" and "parent string" is given, that is, the "substring" is the substring after the infinite cycle of "parent string". Now give n strings and find different "number of parent strings".

Problem solution

When judging the attribution relationship, the parent string can be spliced on both sides. First let the answer to n (as each string is irrelevant), traverse each string, compare it with the following string, find one that can be its parent string, subtract 1 from the answer (this string is not passed by the parent, so subtract), and end the matching (because finding it is enough).

code

using namespace std;
const int N=122;
const ll mod=1000000007;
pair<string,string>all[N];
int yes[N];
int main()
{
    //IOS
    int n;cin>>n;
    for(int i=1;i<=n;i++){
        string t;cin>>t;
        string tt;tt=t+t+t;
        all[i]=make_pair(t,tt);
    }
    ll ans=n;
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            if(all[j].first.length()==all[i].first.length()&&all[j].second.find(all[i].first)!=string::npos){
               ans--;
               break;
            }
        }
    }
    cout<<ans<<'\n';
    return 0;
}

G - contestant Gym - 102890K

meaning of the title


Each of the three groups of ABC has a certain number of people. A total of k people are selected. C must choose C people, and AB must choose at least one person. Find the number of options. Results the model of 1e7 was taken.

Problem solution

The topic turns to the number of schemes in which C individuals are selected from C, K-c individuals are selected from A and B, and at least one person is selected from A and B. Consider the direct combination number calculation, and then subtract the number of schemes in which A chooses K-c and B chooses K-c. (if you can't choose one person without A or b)
Pay attention to judge the rationality first. (there are less than two people left after choosing c)
This problem is difficult in the combination of numbers, because the result needs to be modular. If you divide by 0 according to the method of division, there may be a case. So we need to change it.
There are many ways to find combinatorial numbers, You can see here.
Because there are multiple groups, preprocess first.

code

using namespace std;
const int N=2e5+2;
const ll mod=1000000007;
ll jie[N];
ll tow[N];
ll power(ll a,ll b,ll p)  //return a^b mod p
{
    ll temp = 1;
    while(b)
    {
        if(b & 0x01)
        {
            temp = (temp * (a%p)) % p;
        }
        a = ( (a%p) * (a%p) ) % p;
        b >>= 1;
    }
    return temp%p;
}
void init()
{
    jie[0]=1;
    for(int i=1;i<N;i++)jie[i]=jie[i-1]*i%mod;
    tow[N-1]=power(jie[N-1],mod-2,mod);
    for(int i=N-2;i>=0;i--) tow[i]=tow[i+1]*(i+1)%mod;
}
ll cal(ll n,ll m)
{
    if(m>n) return 0;
    return jie[n]*tow[m]%mod*tow[n-m]%mod;
}

int main()
{
    //IOS
    init();
    int t;cin>>t;
    while(t--){
        ll A,B,C,k,c;
        ll ans=0;
        cin>>A>>B>>C>>k>>c;
        if(k-c<2){cout<<0<<'\n';continue;}
        ll p=k-c;
        ll o=cal(A,p)+cal(B,p);o%=mod;
        ans=cal(A+B,p)-o+mod;
        ans%=mod;
        ans*=cal(C,c);
        ans%=mod;
        cout<<ans<<'\n';
    }
    return 0;
}

The following questions are not read. They are all difficult questions (there are also naked questions). If you don't read them, you won't write them.