2017 Wuhan University Programming Contest 题解

来源:互联网 发布:网络电影东北黑社会 编辑:程序博客网 时间:2024/05/19 00:40

A. One car comes and one car goes

Two cars from the East Station and the west Station started to drive toward each other, and they met 60 miles away from the East Station first. Both of them kept their original speed until reached the other station, then they returned immediately. At a distance of 30 miles from the West Station they met the second time. Calculate the distance between two stations.
Output
Output one number, the answer.
Your answer will be considered as correct if the relative or absolute error is less than
10−4

B.Color

When Asuho was just a little girl, she has been loving stars, as there are so many romantic stories about old legends and the stars.
Today, as usual, Asuho went to the observatory with her beloved boyfriend, Kogasaka Ming, to see the splendid sky of galaxy. Sitting with Kogasaka shoulder to shoulder, Asuho thought nothing could make her happier.
“Asuho,” Kogasaka called Asuho softly. “I have a question about the Hoshizora(night sky with stars).”
“What’s it?” Asuho answered, happily. “I know everything about the stories, you can ask anything.”
Kogasaka smiled, “You see the stars? Just imagine there are
n distinct stars in the sky while
n−1 relationships connect them. Each relationship is between two stars and all stars are connected directly or indirectly. Now you need to divide the
n stars into m different types. Beware that no two directly connected stars should share the same type and some stars cannot be some types. I want you to tell me how many distinct solutions there could be.”
Suddenly the Stella meteor shower appeared, so the lovers forgot the question and started to admire the beautiful Hoshizora.
Asuho thought it was unbelievable that Kogasaka should ask her such a foolish question which she can’t solve. Of course she didn’t wish to reveal her poor math. So can you help her to tell the answer?

#include<bits/stdc++.h>using namespace std;const double eps=1e-10;const double pi=3.1415926535897932384626433832795;const double eln=2.718281828459045235360287471352;#define LL long long#define IN freopen("in.txt", "r", stdin)#define OUT freopen("out.txt", "w", stdout)#define scan(x) scanf("%d", &x)#define mp make_pair#define pb push_back#define sqr(x) (x) * (x)#define pr(x) printf("Case %d: ",x)#define prn(x) printf("Case %d:\n",x)#define prr(x) printf("Case #%d: ",x)#define prrn(x) printf("Case #%d:\n",x)#define lowbit(x) (x&(-x))const LL mod=1e7+9;const int maxn=10005;LL dp[maxn][21];vector<int> g[maxn];int col[maxn][21];int n,m;inline void add(LL &x,LL y){x=(x+y)%mod;}inline void sub(LL &x,LL y){x=(x-y+mod)%mod;}inline void mul(LL &x,LL y){x=(x*y)%mod;}LL tot[maxn];void DFS(int u,int f){    vector<int> v;    v.clear();    for(int p : g[u])    {        if(p==f)continue;        v.pb(p);        DFS(p,u);    }    if(v.size()==0)    {        for(int i=1;i<=m;i++)            if(col[u][i]==1)dp[u][i]=1;else dp[u][i]=0;        return;    }    for(int p : v)    {        tot[p]=0;        for(int i=1;i<=m;i++)add(tot[p],dp[p][i]);    }    for(int i=1;i<=m;i++)    {        if(col[u][i]==0)        {            dp[u][i]=0;            continue;        }        LL temp=1;        for(int p : v)        {            LL tt=tot[p];            sub(tt,dp[p][i]);            mul(temp,tt);        }        dp[u][i]=temp;    }}int main(){    while(scanf("%d%d",&n,&m)==2)    {        for(int i=0;i<=n;i++)        {            g[i].clear();            for(int j=0;j<=m;j++)            {                dp[i][j]=0;                col[i][j]=-1;            }        }        for(int i=1;i<n;i++)        {            int x,y;            scanf("%d%d",&x,&y);            g[x].pb(y);g[y].pb(x);        }        for(int i=1;i<=n;i++)            for(int j=1;j<=m;j++)                scanf("%d",&col[i][j]);        DFS(1,-1);        LL ans=0;        for(int i=1;i<=m;i++)add(ans,dp[1][i]);        printf("%lld\n",ans);    }    return 0;}

C Divide by Six

A positive integer number n is written on a blackboard. It consists of not more than
10510^5
10
​5
​​ digits. You have to transform it into a mogicalnumber by erasing some of the digits, and you want to erase as few digits as possible.
The number is lucky if it consists of at least one digit, doesn’t have leading zeroes and is a multiple of 6. For example, 0, 66,66666 are lucky numbers, and 00, 25, 77 are not.
Write a program which for the given n will find a mogical number such that n can be transformed into this number by erasing as few digits as possible. You can erase an arbitraty set of digits. For example, they don’t have to go one after another in the number n
Print the length of your answer after the erasing.
If it’s impossible to obtain a lucky number, print -1s.

#include<cstdio>#include<algorithm>using namespace std;int dp[100001][3];int dp2[100001];char s[100003];int main(){    while (scanf("%s", s + 1) == 1){        int ans = 0;        bool flag = false;        memset(dp, -1, sizeof(dp));        dp[0][0] = 0;        for (int i = 1; s[i]; i++){            flag |= s[i] == '0';            for (int j = 0, t; j < 3; j++){                t = (j + s[i]) % 3;                if (dp[i - 1][j] != -1){                    int k = dp[i - 1][j] + (t || (s[i] != '0'));                    dp[i][t] = max(dp[i][t], k);                    dp[i][j] = max(dp[i][j], dp[i - 1][j]);                    if (t == 0 && (s[i] & 1) == 0)ans = max(ans, k);                }            }        }        if (ans == 0 && flag)ans = 1;        if(ans)printf("%d\n", ans);        else printf("-1s\n");    }}

D. Events

Every year, the ACM/ICPC team will hold many contests, some of them are training while others are school contests.
In the year of 2017, there are n contests to be held, and at the beginning of year, we plans the time of each contest.
However, as things are changing. Some other events might affect the time of contest and our team leader wants to know some interesting things about the time of some events.

#include<cstdio>#include<cctype>#include<iostream>using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Fork(i,k,n) for(int i=k;i<=n;i++)#define Rep(i,n) for(int i=0;i<n;i++)#define ForD(i,n) for(int i=n;i;i--)#define ForkD(i,k,n) for(int i=n;i>=k;i--)#define RepD(i,n) for(int i=n;i>=0;i--)#define Forp(x) for(int p=Pre[x];p;p=Next[p])#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  #define Lson (o<<1)#define Rson ((o<<1)+1)#define MEM(a) memset(a,0,sizeof(a));#define MEMI(a) memset(a,0x3f,sizeof(a));#define MEMi(a) memset(a,128,sizeof(a));#define MEMx(a,b) memset(a,b,sizeof(a));#define INF (0x3f3f3f3f)#define F (1000000007)#define pb push_back#define mp make_pair #define fi first#define se second#define vi vector<int> #define pi pair<int,int>#define SI(a) ((a).size())#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;#define PRi2D(a,n,m) For(i,n) { \                        For(j,m-1) cout<<a[i][j]<<' ';\                        cout<<a[i][m]<<endl; \                        } #pragma comment(linker, "/STACK:102400000,102400000")typedef long long ll;typedef long double ld;typedef unsigned long long ull;ll mul(ll a,ll b){return (a*b)%F;}ll add(ll a,ll b){return (a+b)%F;}ll sub(ll a,ll b){return ((a-b)%F+F)%F;}void upd(ll &a,ll b){a=(a%F+b%F)%F;}int read(){    int x=0,f=1; char ch=getchar();    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}    return x*f;} #define MAXN (400000+10)ll addv[MAXN<<2],sum[MAXN<<2],minv[MAXN<<2],hminv[MAXN<<2];void pushUp(int o) {    sum[o]=sum[Lson] + sum[Rson];    minv[o]=min(minv[Lson],minv[Rson]);    hminv[o]=min(hminv[Lson],hminv[Rson]);}void pushDown(int o,ll m) {    if (addv[o]) {        addv[Lson]+=addv[o];addv[Rson]+=addv[o];        sum[Lson]+=(m-(m>>1))*addv[o];        sum[Rson]+=(m>>1)* addv[o];        minv[Lson]+=addv[o];        minv[Rson]+=addv[o];        hminv[Lson]=min(hminv[Lson],minv[Lson]);        hminv[Rson]=min(hminv[Rson],minv[Rson]);        addv[o]=0;    }} void build(int l,int r,int o) {    addv[o]=0;    if (l==r) {        sum[o]=minv[o]=hminv[o]=read();        return;    }    int m=(l+r)>>1;    build(l,m,Lson);    build(m+1,r,Rson);    pushUp(o);}void update(int l,int r,int o,int L,int R,ll c) {    if (L<=l&&r<=R) {        addv[o]+=c;        sum[o]+=c*(r-l+1);        minv[o]+=c;        hminv[o]=min(hminv[o],minv[o]);        return;    }    pushDown(o,r-l+1);    int m=(l+r)>>1;    if (L<=m) update(l,m,Lson,L,R,c);    if (m<R) update(m+1,r,Rson,L,R,c);    pushUp(o);}ll ans=INF;void query(int l,int r,int o,int L,int R) {    if (L<=l && r<=R) {        ans=min(ans,hminv[o]);        return;     }    pushDown(o,r-l+1);    int m=(l+r)>>1;    if (L<=m) query(l,m,Lson,L,R);    if (m<R) query(m+1,r,Rson,L,R);}int main(){//  freopen("D.in","r",stdin);//  freopen(".out","w",stdout);    int n=read();    build(1,n,1);    int m=read();    while(m--) {        int a,b,t;        scanf("%d%d%d",&a,&b,&t);        update(1,n,1,a,b,t);        ans=INF;query(1,n,1,a,b);        cout<<ans<<endl;    }       return 0;}

E. Lost in WHU

As one of the most beautiful campus in China, Wuhan University is around several hills, so the road is complex and visitors always lose themselves. Give a undirected graph of WHU of
N points and a deadline, then you should count the number of plan to reach the destination by deadline (the starting point is 1 and the ending point is
N).

#include<bits/stdc++.h>using namespace std;const double eps=1e-10;const double pi=3.1415926535897932384626433832795;const double eln=2.718281828459045235360287471352;#define LL long long#define IN freopen("in.txt", "r", stdin)#define OUT freopen("out.txt", "w", stdout)#define scan(x) scanf("%d", &x)#define mp make_pair#define pb push_back#define sqr(x) (x) * (x)#define pr(x) printf("Case %d: ",x)#define prn(x) printf("Case %d:\n",x)#define prr(x) printf("Case #%d: ",x)#define prrn(x) printf("Case #%d:\n",x)#define lowbit(x) (x&(-x))const LL mod=1e9+7;struct mat{    int n;    LL num[105][105];    void init0(int t)    {        n=t;        for(int i=0;i<=n;i++)            for(int j=0;j<=n;j++)                num[i][j]=0;    }    void init1(int t)    {        n=t;        for(int i=0;i<=n;i++)            for(int j=0;j<=n;j++)                if(i!=j)num[i][j]=0;else num[i][j]=1;    }    mat operator * (const struct mat p)const    {        struct mat ans;        ans.init0(n);        for(int i=1;i<=n;i++)            for(int j=1;j<=n;j++)                for(int k=1;k<=n;k++)                    ans.num[i][j]=(ans.num[i][j]+num[i][k]*p.num[k][j])%mod;        //printf("??");ans.testprint();        return ans;    }           mat operator ^ (int t)const    {        struct mat ans,now;        ans.init1(n);        now.n=n;        for(int i=0;i<=n;i++)            for(int j=0;j<=n;j++)                now.num[i][j]=num[i][j];        while(t>0)        {            if(t&1)ans=ans*now;            now=now*now;            t>>=1;        }        return ans;    }};int n,m;LL dd;int main(){    scanf("%d%d",&n,&m);    struct mat p;    p.init0(n);    p.num[n][n]=1;    while(m--)    {        int x,y;        scanf("%d%d",&x,&y);        p.num[x][y]=p.num[y][x]=1;        if(x==n)p.num[x][y]=0;        if(y==n)p.num[y][x]=0;    }    scanf("%lld",&dd);    struct mat ans=p^dd;    printf("%lld\n",ans.num[1][n]);    return 0;}

F. Soul Artist

Last year, there were three soul artist in the team Abysswatcher. They were all addicted to painting, even when they were on the train. One day, they want to paint a paper. In i-th step, they choose a core grid (x_i, y_i)and paint all the grid near it (the Manhattan distance distance between the core and other grids are no more than ri. After some operates, they want to know the maximum times they painted the same grid.

#include<cstdio>#include<cctype>#include<iostream>using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Fork(i,k,n) for(int i=k;i<=n;i++)#define Rep(i,n) for(int i=0;i<n;i++)#define ForD(i,n) for(int i=n;i;i--)#define ForkD(i,k,n) for(int i=n;i>=k;i--)#define RepD(i,n) for(int i=n;i>=0;i--)#define Forp(x) for(int p=Pre[x];p;p=Next[p])#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  #define Lson (o<<1)#define Rson ((o<<1)+1)#define MEM(a) memset(a,0,sizeof(a));#define MEMI(a) memset(a,0x3f,sizeof(a));#define MEMi(a) memset(a,128,sizeof(a));#define MEMx(a,b) memset(a,b,sizeof(a));#define INF (0x3f3f3f3f)#define F (1000000007)#define pb push_back#define mp make_pair #define fi first#define se second#define vi vector<int> #define pi pair<int,int>#define SI(a) ((a).size())#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;#define PRi2D(a,n,m) For(i,n) { \                        For(j,m-1) cout<<a[i][j]<<' ';\                        cout<<a[i][m]<<endl; \                        } #pragma comment(linker, "/STACK:102400000,102400000")typedef long long ll;typedef long double ld;typedef unsigned long long ull;ll mul(ll a,ll b){return (a*b)%F;}ll add(ll a,ll b){return (a+b)%F;}ll sub(ll a,ll b){return ((a-b)%F+F)%F;}void upd(ll &a,ll b){a=(a%F+b%F)%F;}int read(){    int x=0,f=1; char ch=getchar();    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}    return x*f;} #define MAXN (400000+10)int a[4030][4030]={0},b[4030][4030]={0};pi getB(int x,int y){    return mp((x+y)/2,(y-x+2)/2);}pi getW(int x,int y){    return mp((x+y-1)/2,(y-x+3)/2);}bool is_b(pi p) {    return (p.fi+p.se)%2==0;}pi get(pi p) {    if (is_b(p)) return getB(p.fi,p.se);    return getW(p.fi,p.se);}int getv(pi p) {    pi p2;    if ((is_b(p))) {        p2=getB(p.fi,p.se);        return a[p2.fi+2010][p2.se+2010];    }    else {        p2=getW(p.fi,p.se);        return b[p2.fi+2010][p2.se+2010];    }}void upd(int x,int y,int c,bool bb){//  cout<<x<<' '<<y<<' '<<c<<' '<<bb<<endl;    if (bb) a[x+2010][y+2010]+=c;    else b[x+2010][y+2010]+=c;}void add(int x,int y,int r) {    pi p1=mp(x,y-r),p2=mp(x+r,y),p3=mp(x-r,y),p4=mp(x,y+r);    bool b=is_b(p1);    pi p5=get(p1),p6=get(p2),p7=get(p3),p8=get(p4);    upd(p5.fi,p5.se,1,b);    upd(p6.fi+1,p6.se,-1,b);    upd(p7.fi,p7.se+1,-1,b);    upd(p8.fi+1,p8.se+1,1,b);    r--;if (-1==r) return ;    p1=mp(x,y-r),p2=mp(x+r,y),p3=mp(x-r,y),p4=mp(x,y+r);    b^=1;    p5=get(p1),p6=get(p2),p7=get(p3),p8=get(p4);    upd(p5.fi,p5.se,1,b);    upd(p6.fi+1,p6.se,-1,b);    upd(p7.fi,p7.se+1,-1,b);    upd(p8.fi+1,p8.se+1,1,b);}int main(){//  freopen("F.in","r",stdin);//  freopen(".out","w",stdout);    int n=read(),m=read(),q=read();    For(i,q) {        int x=read(),y=read(),r=read();        add(x,y,r);     }//  For(i,n) {//      For(j,m) if (!is_b(mp(i,j))){//          pi p=get(mp(i,j));//          cout<<'('<<p.fi<<' '<<p.se<<')';//      }puts("");//  }    Rep(i,4020) For(j,4019) {        a[i][j]+=a[i][j-1];    }    For(i,4019) Rep(j,4020) {        a[i][j]+=a[i-1][j];    }    Rep(i,4020) For(j,4019) {        b[i][j]+=b[i][j-1];    }    For(i,4019) Rep(j,4020) {        b[i][j]+=b[i-1][j];    }//  cout<<endl;    ll ans1=0,ans2=0;    For(i,n) {        For(j,m) {            int p=getv(mp(i,j));            if (ans1<p) ans1=p,ans2=1;            else if (ans1==p)++ans2;        }    }    cout<<ans1<<' '<<ans2<<endl;    return 0;}

G. Time Limit Exceeded

Everyone hates the verdict “Time Limit Exceeded” or “TLE”. However, sometimes, we can’t come up with a “elegant” solution which is clear and fast.
Our problem setter also hates “TLE”, but he is dumb and can only work out what a problem is. He can’t really solve it. We called him “Zui Qiang Xuan Shou”
One day, he got a problem, again, he said “I got it! It is **”, he spoke so fast that no one knew what he said. Luckily, he typed his solution—

#include <stdio.h>int main(){  int n;  int *vec;  scanf("%d", &n);  vec = malloc(sizeof(int) * n);  for (int i = 0; i < n; i++)  {    int t;    scanf("%d", &t);    vec.push_back(t);  }  long long ans = 0;  for (int i = 0; i < n; i++)    for (int j = 0; j < n - 1; j++)      if (vec[j] > vec[j+1])      {        ans++;        swap(vec[j], vec[j+1]);      }  printf("%lld\n", ans);  return 0;}

He said that it should get AC small cases, but he might receive “Time Limit Exceeded”.
As he clicked the “submit” button, the network is down. So he went to the dinning hall and ask you to correct his solution.Your program should output exact same things as the program listed above.

#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<functional>#include<iostream>#include<cmath>#include<cctype>#include<ctime>#include<vector>using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Fork(i,k,n) for(int i=k;i<=n;i++)#define Rep(i,n) for(int i=0;i<n;i++)#define ForD(i,n) for(int i=n;i;i--)#define RepD(i,n) for(int i=n;i>=0;i--)#define Forp(x) for(int p=pre[x];p;p=next[p])#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  #define Lson (x<<1)#define Rson ((x<<1)+1)#define MEM(a) memset(a,0,sizeof(a));#define MEMI(a) memset(a,127,sizeof(a));#define MEMi(a) memset(a,128,sizeof(a));#define INF (2139062143)#define F (100000007)#define MAXN (10000001)typedef long long ll;ll mul(ll a,ll b){return (a*b)%F;}ll add(ll a,ll b){return (a+b)%F;}ll sub(ll a,ll b){return (a-b+(a-b)/F*F+F)%F;}void upd(ll &a,ll b){a=(a%F+b%F)%F;}int A[MAXN],t[MAXN];int fl=0;   ll merge_count(int l,int r){    int n=r-l+1,m=(l+r)>>1;    if (n<=1) return 0;    ll cnt=0;    cnt+=merge_count(l,m);    cnt+=merge_count(m+1,r);    int p=l,q=m+1,ai=l;    while (ai<=r)    {        if ( q>r || (p<=m && A[p]<=A[q] ) )        {            t[ai++]=A[p++];        }        else {            cnt+=m-p+1;            t[ai++]=A[q++];        }    }       Fork(i,l,r) A[i]=t[i];    return cnt;}int n=10000000;int main(){//  freopen(".in","r",stdin);//  freopen(".out","w",stdout);    int n;    cin>>n;    For(i,n) scanf("%d",&A[i]);    cout<<merge_count(1,n)<<endl;    return 0;}

H. Werewolf

Generally, ACMers play Werewolf game anywhere when they go out for any programming contests. There are several roles in this game, including werewolves, villagers, seer, witch, hunter, cupid……
Here is the rule of the game:
The werewolves Each night the werewolves kill a player.
The villagers The villagers has no skills.
The seer Each night the seer can look at a card of a player of his choice to find out the real.
The hunter If the hunter gets killed, the hunter has the power to retaliate by killing a player of his choice immediately.
The cupid On the first night, cupid picks 2 players who he denotes as lovers. Those 2 players will fall madly in love with each another. If one of the lover dies, the other, out of sadness, dies immediately.
The witch The witch knows how to make up 2 extremely powerful potions. One healing potion, which can revive the player that has been killed by the werewolves. One poison potion, which when used at night can kill a player. The witch must use each potion only once during the game.

After each night, everyone wakes up, the god(game master) shows all players which player was killed during the night. After discussion, each player must select one player that they want to eliminate when they vote.

Generally, the werewolves do not select their teammates, but other roles do select anyone when voting. Here comes the problem. How many werewolves at most under the given voting case.

#include<cstdio>#include<cstring>#include<algorithm>#include<vector>using namespace std;vector<pair<int, int>> v[500001];int dp[500001][2];bool used[500001], used2[500001];int n, s, t;bool dfs(int i){    used[i] = true;    for (unsigned int j = 0; j < v[i].size(); j++){        int k = v[i][j].first, id = v[i][j].second;        if (!used2[id]){            if (used[k]){                v[i].erase(v[i].begin() + j);                v[k].erase(find(v[k].begin(), v[k].end(), make_pair(i, id)));                s = i; t = k;                return true;            }            used2[id] = true;            if (dfs(k))return true;        }    }    return false;}void dfs2(int i, int fa){    used[i] = true;    dp[i][0] = 0; dp[i][1] = 1;    for (unsigned int j = 0; j < v[i].size(); j++){        int k = v[i][j].first;        if (k != fa){            dfs2(k, i);            dp[i][0] += max(dp[k][0], dp[k][1]);            dp[i][1] += dp[k][0];        }    }}int main(){    scanf("%d", &n);    for (int i = 1; i <= n; i++){        int t;        scanf("%d", &t);        v[i].push_back(make_pair(t, i));        v[t].push_back(make_pair(i, i));    }    int ans = 0, t1, t2;    for (int i = 1; i <= n; i++){        if (!used[i]){            dfs(i);            dfs2(s, 0); t1 = dp[s][0];            dfs2(t, 0); t2 = dp[t][0];            ans += max(t1, t2);        }    }    printf("%d", ans);}
0 0