第一屆"進化論杯"月賽 解題報告

Problem A: derivative

思路:水題。算出二階導數,直接 printf 結果。
在求出二階導數後能夠不馬上化簡,此時式中帶有大量 e^(-x) 項。此時直接能夠代入 ln|x0|,把式子丟給程序運算便可,能稍微提升解題速度。
代碼:c++

#include<bits/stdc++.h>
#include<vector>
using namespace std;
typedef long long ll;

int read(){
    char ch=getchar();int x=0,f=1;
    while (ch<'0' || ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*=f;
}


int main(){
    int n=read();
    while (n--){
        double x;
        scanf("%lf",&x);
        x=1/fabs(x);
        printf("%.3lf\n",(1+x)*(1+x)*(1+x)*(1+x)/(2.0*x*(1+x)*x-x*(1+x)*(1+x)));
    }
    return 0;
}

Problem B: fzuacmicpc

思路:水題。在環中找字符串並統計個數。複製字符串鏈接在末尾,而後枚舉起點便可。spa

代碼:3d

#include<bits/stdc++.h>
#include<vector>
using namespace std;
typedef long long ll;

int read(){
    char ch=getchar();int x=0,f=1;
    while (ch<'0' || ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*=f;
}


char ss[200020];

int main(){
    cin>>ss;
    int len=strlen(ss);
    for (int i=0; i<len; i++){
        if (ss[i]<='Z') ss[i]+=32; 
    }
    for (int i=0; i<len; i++){
        ss[len+i]=ss[i]; 
    }
    int ans=0;
    for (int i=0; i<len; i++){
        if (ss[i]=='f' && ss[i+1]=='z' && ss[i+2]=='u' && ss[i+3]=='a' &&ss[i+4]=='c' &&ss[i+5]=='m' &&ss[i+6]=='i' &&ss[i+7]=='c' && ss[i+8]=='p' && ss[i+9]=='c')
            ans++;
        if (ss[i]=='c' && ss[i+1]=='p' && ss[i+2]=='c' && ss[i+3]=='i' &&ss[i+4]=='m' &&ss[i+5]=='c' &&ss[i+6]=='a' &&ss[i+7]=='u' && ss[i+8]=='z' && ss[i+9]=='f')
            ans++;
    }
    cout<<ans;
    return 0;
}

Problem C: heroes


Problem D: ksubstring

思路:調試

代碼:code

#include<bits/stdc++.h>
using namespace std; 

char ss[1000010];
int cnt[1000010][30];

int find(int l,int r,int k){
    if (l>r) return 0;
    int t=l-1,ans=0;
    int f=0;
    for (int i=l; i<=r; i++){
        int a=ss[i]-'a';
        if (cnt[r][a]-cnt[l-1][a]<k){
            f=1;
            ans=max(ans,find(t+1,i-1,k));
            t=i;
        }
    }
    
    if (f){
        ans=max(ans,find(t+1,r,k));
        return ans;
    }
    else return r-l+1;
}

int main(){
    int n,k;
    cin>>n>>k;
    scanf("%s",ss+1);
    int len=strlen(ss+1);
    for (int i=1; i<=len; i++){
        for (int j=0; j<=30; j++)
            cnt[i][j]=cnt[i-1][j];
        cnt[i][ss[i]-'a']++;
    }
    int ans=find(1,len,k);
    if (ans) printf("%d",ans);
    else printf("-1");
    return 0;
}

Problem E: magicwall


Problem F: monoid-group

思路:水題。雖然題目很長,但讀完題目發現只須要模擬就能過。blog

代碼:ci

#include<bits/stdc++.h>
#include<vector>
using namespace std;
typedef long long ll;

ll read(){
    char ch=getchar();ll x=0,f=1;
    while (ch<'0' || ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*=f;
}

int num[1000010];

int main(){
    ll n=read(),k=read();
    for (int i=1; i<=n; i++)
        num[i]=n-i+1;
    ll tot=n*(n-1)/2;
    if (k==tot){
        printf("YES\n");
        for (int i=1; i<=n; i++)
            printf("%d ",num[i]);
        return 0;
    }
    for (int i=1; i<=n; i++){
        ll t=n-i+1;
        t=t*(t-1)/2;
        if (tot-t>k){
            i--;
            t=n-i+1;
            t=t*(t-1)/2;
            int res=(tot-t)-k,x=0;
            for (int j=i; j<=n; j++){
                num[j]=++x;
            }
            swap(num[i],num[i+res]);
            printf("YES\n");
            for (int j=1; j<=n; j++)
                printf("%d ",num[j]);
            return 0;
        }
    }
    printf("NO");
    return 0;
}

Problem G: ninja




思路:水題。雖然題目很長,但讀完題目發現只要找到華麗值最大的邊,而後在上面反覆橫跳k次便可。
計算華麗值:相似弗洛伊德;鄰接表存圖,每次枚舉 i , j , k 判斷(i,j)和(j,k)是否有邊,如有,則(i,k)的華麗值加上(i,j)*(j,k)。字符串

代碼:get

#include<bits/stdc++.h>
#include<vector>
using namespace std;
typedef long long ll;

ll read(){
    char ch=getchar();ll x=0,f=1;
    while (ch<'0' || ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*=f;
}

ll p[210][210],v[210][210];

int main(){
    ll n=read(),m=read(),k=read();
    for (int i=1; i<=m; i++){
        ll a=read(),b=read(),c=read();
        v[a][b]=c;
        v[b][a]=c;
    }
    ll ans=0;
    for (int i=1; i<=n; i++){
        for (int j=1; j<=n; j++){
            ll tot=0;
            for (int k=1; k<=n; k++){
                if (v[i][k] && v[k][j]) tot+=v[i][k]*v[k][j];
            }
            ans=max(ans,tot);
        }   
    }
    printf("%lld",ans*k);
    return 0;
}

Problem H: permutation-generation

思路:考場上思路不清晰,用了很奇怪的作法調試了好久才過。string

代碼:

咕咕咕
相關文章
相關標籤/搜索