NYNU ACM 藍橋杯選拔賽 解題報告

ACM_e發表於2017-12-02

內網比賽 後面幾題自己看課本 一下題解為外網和內網前幾題題解

A
這題需要考慮的問題是:該怎樣放人、載人才能到達B地且時間最少,仔細想想,只用在某一個地方放人下去(就是說只用交換一次)。

現在的問題就變為了:該在哪個地方放人下去,帶回終點,兩人一起到終點,時間最少(首先車帶一個人行駛一段距離然後丟下,折回找另外一個人,半路碰上,帶回終點剛好與第一人共到B點)

這樣問題就好解決了,設那個放下的點為x,那麼就有:(s-x)/a=2*(2*x/(a+b)-x/b)+(s-x)/b

化簡得:x=(b+a)*s/(b+3a)

既然放下的那個點已經確定好了,那麼時間也簡單了,時間為:x/b+(s-x)/a,(x/b)為那個點前一段所用的時間,[(s-x)/a]為那個點後一段所用的時間。

#include<bits/stdc++.h> 
using namespace std;
int main(){
    double n, a, b;
    scanf("%lf%lf%lf", &n, &a, &b);
    double m = (b + a)/(b - a);
    double x = 2 * m + 1;
    double y = 2 * a * m + 2 * a + b;
    double t = x * n / y;
    printf("%.6f\n", t); 
    return 0;
}

B

排序 設定兩個指標 一個從頭一個從尾部 向中間掃描 看有幾種方案

#include <iostream>
#include <algorithm>
using namespace std;
#define mo 1000005
int a[mo];


int main()
{
    int n,m;
    while(cin>>n>>m)
    {
        for(int i=0;i<n;i++)
        {
            cin>>a[i];
        }

        sort(a,a+n);
        int l=0,r=n-1;
        int ans=0;
        int sum=0,k=0;
        while(l<=r)
        {
            ans=0;
            for(;r>l;r--)
            {
                if(ans+a[r]<=m) ans+=a[r];
                else break;
            }


            for(;l<=r;l++)
            {
                if(ans+a[l]<=m) ans+=a[l];
                else break;
            }
            sum+=m-ans;
            k++;
        }
        cout<<sum<<' '<<k<<endl;
    }
}

C
暴力搜尋

#include<iostream>
#include<string>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <cstdio>
using namespace std;
int d[10];
int tag[10];
int sum;
int dp[10000005];
void run()
{
    int x=0,y=0,z=0;
    for(int i=1;i<=9;i++)
    {
        x=x*10+tag[i];
        y=0;
        for(int j=i+1;j<=9;j++)
        {
            y=y*10+tag[j];
            z=0;
            //cout<<i<<' '<<j<<' '<<endl;
            if(j-i>=9-j&&j<9)
            {
                for(int k=j+1;k<=9;k++)
                {
                    z=z*10+tag[k];
                }
               //cout<<x<<' '<<y<<' '<<z<<' '<<x<<' '<<y/z<<endl;
               if(z==0||y<z) continue;
               if(y%z==0) dp[x+y/z]++;
            }
        }
    }
}
void bfs(int t,int x,int s)
{
    tag[x]=s;
    if(t==9)
    {
        run();
        //for(int i=1;i<=9;i++)cout<<tag[i]<<' ';cout<<endl;
        sum++;
    }
    for(int i=1;i<=9;i++)
    {
        if(d[i]==0)
        {
            d[i]=1;
            bfs(t+1,x+1,i);
            d[i]=0;
        }
    }
}

int main()
{
    sum=0;
    bfs(0,0,0);
    //cout<<sum<<endl;
    int n;
    while(cin>>n)
    {
        cout<<dp[n]<<endl;
    }
}

D

蛇形填數 變形
按照題意模擬即可

#include <iostream>
#include <cstring>
int a[1001][1001];
int main()
{
    int T,n;
    std::cin>>T;
    while(T--)
    {
        std::memset(a,0,sizeof(a));
        std::cin>>n;
        if(n==1)std::cout<<"#\n";
        else if(n==2)std::cout<<"##\n# \n";
        else
        {
            int k=1,x=n-1,y=n,n1=n-3;
            for(int i=1;i<=n;i++)a[1][i]=a[i][1]=a[n][i]=1;
            while(n1--)
            {
                if(k==1){while(true){a[x][y]=1;if(a[x-2][y]){k=2;break;}x--;}}
                else if(k==2){while(true){a[x][y]=1;if(a[x][y-2]){k=3;break;}y--;}}
                else if(k==3){while(true){a[x][y]=1;if(a[x+2][y]){k=4;break;}x++;}}
                else{while(true){a[x][y]=1;if(a[x][y+2]){k=1;break;}y++;}}
            }
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)if(a[i][j])std::cout<<"#";else std::cout<<" ";
                std::cout<<std::endl;
            }
        }
    }
}

E
簽到

#include <iostream>
#include <algorithm>
int main()
{
    int n,a[100000],k;
    std::cin>>n>>k;
    for(int i=0;i<n;i++)std::cin>>a[i];
    std::sort(a,a+n);
    for(int i=n-1;i>=0;i--){if(a[i]<k)break;std::cout<<a[i]<<std::endl;}
}

F
數論 找規律打表

#include <iostream>
#include <cmath>
struct aaa
{
    int a[1000],t=0,n=0;
}aa[10001];
int main()
{
    int k=3,n,t=1;
    aa[1].a[++aa[1].t]=0;
    std::cin>>n;
    for(int i=1;t<=n;i++)
    {
        int g=t;++t;
        aa[t].a[++aa[t].t]=i;
        aa[t].n+=i;
        for(int j=1;j<=g;j++)
        {
            ++t;
            for(int k=1;k<=aa[j].t;k++)aa[t].a[k]=aa[j].a[k],aa[t].n=aa[j].n;
            aa[t].t=aa[j].t;
            aa[t].a[++aa[t].t]=i;aa[t].n+=i;
        }
    }
    long long s1=0;
    for(int i=1;i<=n;i++)s1+=aa[i].n;
    long long s=0;
    for(int i=1;i<=aa[n].t;i++)s+=std::pow(k,aa[n].a[i]);
    std::cout<<s<<" "<<s1<<std::endl;
}

G

線段樹區間覆蓋加區間加,兩個zkw標記

#include<bits/stdc++.h>
using namespace std;
#define maxn 1000000
int add[maxn*5];
int sub[maxn*5];
void updata(int l,int r,int x,int y,int z,int in){
    if(z==1){
    if(sub[in]){
        add[in]=0;
        sub[in*2]=1;
        sub[in*2+1]=1;
        sub[in]=0;
    }
    }
    else{
    add[in*2]+=add[in];
    add[in*2+1]+=add[in];
    add[in]=0;
    }
    if(l==x&&r==y){
        if(z==1){
           add[in]++;
        }
        else{
           sub[in]=1;
        }
        return ;
    }
    int mid=(l+r)/2;
    if(x>mid){
        updata(mid+1,r,x,y,z,in*2+1);
    }
    else if(y<=mid){
        updata(l,mid,x,y,z,in*2);
    }
    else{
        updata(l,mid,x,mid,z,in*2);
        updata(mid+1,r,mid+1,y,z,in*2+1);
    }
}
int query(int l,int r,int in,int z){
   if(sub[z]) return 0;
   if(l==r){
       return add[z];
   }
   int mid=(l+r)/2;
    if(in<=mid){
        return add[z]+query(l,mid,in,z*2);
    }
    else{
        return add[z]+query(mid+1,r,in,z*2+1);
    }
}
int main(){
    int n,m;
    cin>>n>>m;
    memset(sub,0,sizeof(sub));
    memset(add,0,sizeof(add));
    for(int j=0;j<m;j++){
        int x,y,z;
        scanf("%d%d%d",&z,&x,&y);
        updata(1,n,x,y,z,1);
    }
    for(int j=1;j<=n;j++){
        cout<<query(1,n,j,1)<<endl;
    }

}
/*
10 6
1 5 6
1 5 7
1 6 9
1 5 7
2 1 10
1 1 10
*/

H
2017 西安區域賽 原題

#include <iostream>
using namespace std;
int main()
{
    double a,b;
    cin>>a>>b;
    printf("%.1f",a/(a+b));
}

I
數論
百度就好

#include <iostream>
using namespace std;
int main()
{
int a,b;
    cin>>a>>b;
    cout<<a*b-a-b<<endl;
}

J
貪心

#include <stdio.h>
#include <string.h>
int main()
{
    int k,l,max,z;
    char s[105],ans[105];

        scanf("%s%d",s,&k);
        l = strlen(s);
        for(int i=0,q=-1;i<l-k;i++)
        {
            max = 0;
            for(int j=q+1;j<=k+i;j++)
                if(max < s[j])
                    max = s[j] , q = j;
            ans[i] = max;
        }
        ans[l-k] = '\0';
        puts(ans);

    return 0;
}

K (網路賽)
防ak
樹鏈剖分+線段樹zkw標記

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
struct aaa{long long x,y;}aa[1000001];
bool cmp(aaa A,aaa B){return A.x<B.x;}
long long d[100001],a1[100001],n,t1=0,t2=1,a2[100001],a3[100001],a4[100001],a5[100001];//d為子樹長度,a1為輔助陣列,a2為樹鏈首節點,a3為節點所屬樹鏈,a4為節點對應序號
long long a[800004],b[800004],b1[400004],la[400004],lb[400004],s=0;
bool p[100001];
void dfs(long long v)
{
    d[v]=++t1;
    long long k1=(long long)(std::lower_bound(a1+2,a1+n+1,v)-a1),k2=(long long)(std::upper_bound(a1+2,a1+n+1,v)-a1);
    for(long long i=k1;i<k2;i++)
    {
        if(p[aa[i].y])continue;
        p[aa[i].y]=1;
        dfs(aa[i].y);
    }
    d[v]=t1-d[v]+1;
}

void shulian(long long v)
{
    long long k1=(long long)(std::lower_bound(a1+2,a1+n+1,v)-a1),k2=(long long)(std::upper_bound(a1+2,a1+n+1,v)-a1);
    a4[v]=++t1;
    if(!a2[t2])a2[t2]=v;
    a3[v]=t2;
    long long h=-1,h1=0;
    for(long long i=k1;i<k2;i++)
    {
        if(p[aa[i].y])continue;
        if(d[aa[i].y]>h)h=d[aa[i].y],h1=aa[i].y;
    }
    if(h!=-1)
    {
        p[h1]=1;
        shulian(h1);
    }
    for(long long i=k1;i<k2;i++)
    {
        if(p[aa[i].y])continue;
        p[aa[i].y]=1;
        t2++;
        shulian(aa[i].y);
    }
}

void xiugai(long long v,long long l,long long r,long long x,long long y,long long z,long long p1)
{
    //std::cout<<v<<" "<<l<<" "<<r<<" "<<x<<" "<<y<<" "<<z<<" "<<p1<<std::endl;
    long long mid=(l+r)/2;
    if(l!=r)
    {
        b1[v*2]+=lb[v],lb[v*2]+=lb[v],a[v*2]+=a[v]+b[v*2]*la[v],la[v*2]+=la[v];
        b1[v*2+1]+=lb[v],lb[v*2+1]+=lb[v],a[v*2+1]+=a[v]+b[v*2+1]*la[v],la[v*2+1]+=la[v];
        la[v]=lb[v]=a[v]=0;
    }
    if(l==x&&y==r)
    {
        if(p1==1)b[v]+=z,b1[v]+=z,lb[v]+=z;
        else if(p1==2)a[v]+=b1[v]*z,la[v]+=z;
        else s+=a[v];
        //std::cout<<a[v]<<" "<<b[v]<<std::endl;
        return;
    }
    if(mid>=y)xiugai(v*2,l,mid,x,y,z,p1);
    else if(mid<x)xiugai(v*2+1,mid+1,r,x,y,z,p1);
    else xiugai(v*2,l,mid,x,mid,z,p1),xiugai(v*2+1,mid+1,r,mid+1,y,z,p1);
}
int main()
{
    long long q,x,y,z;
    std::cin>>n;std::memset(d,0,sizeof(d));std::memset(p,0,sizeof(p));
    for(long long i=2;i<=n;i++){std::cin>>aa[i].x;aa[i].y=i;a5[i]=aa[i].x;}
    std::sort(aa+2,aa+1+n,cmp);
    for(long long i=2;i<=n;i++)a1[i]=aa[i].x;
    p[1]=1,dfs(1);
    std::memset(a2,0,sizeof(a2));
    std::memset(p,0,sizeof(p));
    p[1]=1,t1=0,shulian(1);
    //for(long long i=1;i<=n;i++)std::cout<<a4[i]<<std::endl;
    std::cin>>q;
    while(q--)
    {
        std::cin>>z>>x>>y;
        while(true)
        {
            if(a3[x]==1)
            {
                xiugai(1,1,n,1,a4[x],y,z);
                break;
            }
            xiugai(1,1,n,a4[a2[a3[x]]],a4[x],y,z);
            x=a5[a2[a3[x]]];
        }//std::cout<<std::endl;
    }

    //for(long long i=1;i<=5;i++)std::cout<<a[i]<<" "<<b[i]<<std::endl;
    for(long long i=1;i<=n;i++)s=0,xiugai(1,1,n,a4[i],a4[i],0,0),std::cout<<s<<std::endl;
}

相關文章