AtCoder Beginner Contest 160题解

  The first fight atcoder, beginner course and cfdiv3 difficulty feeling almost, that is the difficulty and F AE gap a little big, but actually #ifndef ONLINE_JUDGE read and write files into the RE, white hair gave a penalty when 2

A.

Question is intended: to a string of 6 and 3 when the same bit position and phase 5 and 6 while the output or Output Yes No bit 4

Solution: string simulation questions  

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+5;
const int mod = 1e9+7;
ll qpow(ll a,ll b){ll res=1;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}

int main ()
{
    string a;
    cin>>a;
    if(a[2]==a[3]&&a[4]==a[5])printf("Yes\n");
    else printf("No\n");
    return 0;
}
View Code

B.

Meaning of the questions: There are six kinds of coins in denominations of 500,100,50,10,5,1, a 500 face value of the coins will get pleasure 1000, a par value of 5 coins will get pleasure 5, and now you have to ask X Japan coins, most of the pleasure they get replaced after the coin is.

Solution: greedy, before the election of 5500 re-election.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+5;
const int mod = 1e9+7;
ll qpow(ll a,ll b){ll res=1;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}

int main ()
{
    ll x;
    scanf("%lld",&x);
    ll ans = x/500*1000;
    x-=x/500*500;
    years + = x / 5 * 5 ;
    cout<<ans<<endl;
    return 0;
}
View Code

C.

The meaning of problems: given a point on a circumference of a circle n K, find any point select a starting point, traverse the shortest path required to complete the n points away.

Solution: enumerate each origin, due to the complete traversal of n points so the final stop position is certainly its adjacent two points in a can O (1) update the answer.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5+5;
const int mod = 1e9+7;
ll qpow(ll a,ll b){ll res=1;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
int a[maxn];
int main()
{
    int n,k;
    scanf("%d%d",&k,&n);
    for(int i = 1;i <= n;++i)scanf("%d",&a[i]);
    int ans = 0;
    for(int i = 1;i <= n;++i)
    {
        int tmp = min(a[i]-a[1],k-a[i]+a[1]);
        int tmp2 = min(a[i]-a[i-1],k-a[i]+a[i-1]);
        ans=max(ans,max(tmp,tmp2));
    }
    cout<<ans<<endl;
    return 0;
}
View Code

D.

The meaning of problems: there is no n a n vertices to FIG edges, wherein the n-1 sides is the i and i-1, as well as a specified edge xy, for 1 <= k <n, the shortest distance in FIG seek disordered point k log

Solution: Since n <= 2000, it is possible to enumerate each of the starting point i, bfs i to find each point shortest dist [j], then ans [dist [j]] ++, because it is so disordered point The answer is divided by 2.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+5;
const int mod = 1e9+7;
ll qpow(ll a,ll b){ll res=1;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
int ans[maxn];
int n,x,y,mi;
int dist[maxn];
void bfs()
{
    memset(dist,-1,sizeof(dist));
    dist [I] = 0 ;
    queue<int>q;
    q.push(mi);
    while(!q.empty())
    {
        int now = q.front();
        q.pop();
        if(now+1<=n&&dist[now+1]==-1){
            dist[now+1]=dist[now]+1;
            q.push(now+1);
        }
        if(now-1<=n&&dist[now-1]==-1){
            dist[now-1]=dist[now]+1;
            q.push(now-1);
        }
        if(x==now)
        {
            if(y>=mi&&dist[y]==-1){
                dist[y]=dist[now]+1;
                q.push(y);
            }
        }
        if(y==now)
        {
            if(y>=mi&&dist[x]==-1){
                dist[x]=dist[now]+1;
                q.push(x);
            }
        }
    }
}
int main ()
{
    scanf("%d%d%d",&n,&x,&y);
    for(int i = 1;i < n;++i)
    {
        I = i;
        bfs();
        for(int j = i+1;j <= n;++j)
            years [dist [j]] ++ ;
    }
    for(int i = 1;i < n;++i)printf("%d\n",ans[i]);
    return 0;
}
View Code

 

E.

Meaning of the questions: There are A red apple, B green apples, C a colorless apple, you can put apples colorless dyed red or blue, you need to eat apples red X, Y of a green apple, each Apple has a delicious value, delicious seek maximum value that can be obtained.

Solution: greedy, first so delicious apples by value descending order, select the top x + y apples, red apples statistics inside and number of the number of apple green, red if there is a number greater than the number of X or Y is greater than the green case , then subtract x + y before a delicious value inside a small red or blue apples, then after a + b + cxy apples in selecting the corresponding number of red / blue apples.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+5;
const int mod = 1e9+7;
ll qpow(ll a,ll b){ll res=1;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
struct node
{
    int val,type;
    friend bool operator < (node a,node b){
        return a.val>b.val;
    }
}a[maxn*3];
int main()
{
    int x,y,r,g,b;
    cin>>x>>y>>r>>g>>b;
    int tot = 0;
    for(int i = 1;i <= r;++i)
    {
        to ++ ;
        a[tot].type=1;
        scanf("%d",&a[tot].val);
    }
    for(int i = 1;i <= g;++i)
    {
        to ++ ;
        a[tot].type=2;
        scanf("%d",&a[tot].val);
    }
    for(int i = 1;i <= b;++i)
    {
        to ++ ;
        a[tot].type=3;
        scanf("%d",&a[tot].val);
    }
    Luckily (a + 1 , a + 1 + all);
    int cnt1, cnt2;
    cnt1=cnt2=0;
    ll sum = 0;
    for(int i = 1;i <= x+y;++i)
    {
        if(a[i].type==1)cnt1++;
        else if(a[i].type==2)cnt2++;
        if(a[i].type==1&&cnt1>x)continue;
        if(a[i].type==2&&cnt2>y)continue;
        sum+=a[i].val;
    }
    if(cnt1>x)
    {
        int res = cnt1-x;
        for(int i = x+y+1;i <= x+y+r&&res;++i)
        {
            if(a[i].type!=1)sum+=a[i].val,res--;
        }
    }
    if(cnt2>y)
    {
        int res = cnt2-y;
        for(int i = x+y+1;i <= x+y+r&&res;++i)
        {
            if(a[i].type!=2)sum+=a[i].val,res--;
        }
    }
    cout<<sum<<endl;
    return 0;
}
View Code

 

F.

The meaning of problems: Given a n vertices unrooted trees, for 1 <= k <= n, the number of programs to find the node k is the starting point to all the nodes marked with labels. Reference numeral playing rule is first written to the node K 1, then in accordance with 2,3, ..., n the order of the random selection of any one node have fought write reference numerals without a fight adjacent node digital.

Solution: How to get to first consider is the root of the number of programs. Determined for each program every single subtree of node 1 in order of appearance of each point must be determined to Son [1] represents the child node 1, can be introduced ans [1] = (n-1)! * Π (ans [son [1]]) / Π (size [son [i]]) !, according to this equation dp back to the root node as the root is determined in each answer.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5+5;
const int mod = 1e9+7;
ll qpow(ll a,ll b){ll res=1;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll d[maxn],p[maxn],size[maxn],ans[maxn],jec[maxn];
int n;
vector<int>v[maxn];
void dfs1(int now,int pre)
{
    size[now]=1;
    d[now]=1;
    for(int i = 0;i < v[now].size();++i){
        int to = v[now][i];
        if(to==pre)continue;
        dfs1(to,now);
        size[now]+=size[to];
    }
    d[now] = jec[size[now]-1];
    for(int i = 0;i < v[now].size();++i){
        int to = v[now][i];
        if(to==pre)continue;
        d[now]=d[now]*d[to]%mod*qpow(jec[size[to]],mod-2)%mod;
    }
}
void dfs2(int now,int pre)
{
    ll tmp=1;
    if(now!=1)
    {
        tmp=ans[pre]*jec[size[now]]%mod*qpow(jec[n-1],mod-2)%mod*qpow(d[now],mod-2)%mod*jec[n-size[now]-1]%mod;
    }
    else {
        for(int i = 0;i < v[now].size();++i){
            int to = v[now][i];
            if(to==pre)continue;
            dfs2(to,now);
        }
        return ;
    }
    ans[now]=jec[n-1];
    ans[now]=ans[now]*tmp%mod*qpow(jec[n-size[now]],mod-2)%mod;
    for(int i = 0;i < v[now].size();++i){
        int to = v[now][i];
        if(to==pre)continue;
        ans[now]=ans[now]*d[to]%mod*qpow(jec[size[to]],mod-2)%mod;
    }
    for(int i = 0;i < v[now].size();++i){
        int to = v[now][i];
        if(to==pre)continue;
        dfs2(to,now);
    }
}
int main ()
{
    scanf("%d",&n);
    jec[0]=1;
    for(int i = 1;i <= n;++i)jec[i]=jec[i-1]*i%mod;
    for(int i = 1;i < n;++i)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        v[a].push_back(b);
        v[b].push_back(a);
    }
    dfs1 ( 1 , 0 );
    years [ 1 ] = d [ 1 ];
    dfs2(1,0);
    for(int i = 1;i <= n;++i)printf("%lld\n",ans[i]);
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/aaddvvaanntteezz/p/12590234.html