1. 程式人生 > >ACM-ICPC 2018 焦作賽區網路預賽 題解

ACM-ICPC 2018 焦作賽區網路預賽 題解

A

#include<iostream>
#include<cstdio>
using namespace std;
char s[30];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        scanf("%s",s);
        if((s[0]=='j'||s[0]=='J')&&(s[1]=='E'||s[1]=='e')&&(s[2]=='s'||s[2]=='S')&&(s[3]=='s'||s[3]=='S')&&(s[4
]=='I'||s[4]=='i')&&(s[5]=='E'||s[5]=='e')&&s[6]=='\0') cout<<"Good guy!"<<endl; else cout<<"Dare you say that again?"<<endl; } }

B dp[i][j][0]表示使用了前i個符號,以第j個數字結尾 的最大值 dp[i][j][1]表示使用了前i個符號,以第j個數字結尾 的最小值

#include<iostream>
#include<cstdio> #include<cstring> using namespace std; const long long inf=9e18; long long dp[6][1010][2]; char s[6]; long long a[1010]; int len; long long cal(long long a,char c,long long b) { if(c=='+') return a+b; else if(c=='-') return a-b; else if(c=='*') return
a*b; else return a/b; } int main() { int t; scanf("%d",&t); int n,m; long long k; long long maxx,minn; long long ans1,ans2; while(t--) { scanf("%d%d%lld",&n,&m,&k); for(int i=0;i<n;i++) { scanf("%lld",&a[i]); } getchar(); scanf("%s",s); len=strlen(s); for(int i=0;i<len;i++) for(int j=0;j<n;j++) { dp[i][j][0]=-inf; dp[i][j][1]=inf; } maxx=k; minn=k; int tj=0; for(int i=0;i<len;i++) { if(i) { while(dp[i-1][tj][0]==-inf) tj++; maxx=dp[i-1][tj][0]; minn=dp[i-1][tj][1]; } for(int j=i?tj+1:0;j<n;j++) { if(s[i]=='/'&&a[j]==0) { if(i&&dp[i-1][j][0]!=-inf) { maxx=max(maxx,dp[i-1][j][0]); minn=min(minn,dp[i-1][j][1]); } continue; } ans1=cal(maxx,s[i],a[j]); ans2=cal(minn,s[i],a[j]); dp[i][j][0]=max(ans1,ans2); dp[i][j][1]=min(ans1,ans2); if(i&&dp[i-1][j][0]!=-inf) { maxx=max(maxx,dp[i-1][j][0]); minn=min(minn,dp[i-1][j][1]); } } } maxx=-inf; for(int j=(len!=1)?tj+1:0;j<n;j++) maxx=max(maxx,dp[len-1][j][0]); printf("%lld\n",maxx); } }

C

D

E

F

G 指數迴圈節+快速冪

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const long long mo=1e9+7;
const int N=100005;
char n[N];
long long mul(long long a,long long b)
{
    long long ans=0;
    a%=mo;
    while(b)
    {
        if(b&1)
        {
            ans=(ans+a)%mo;
        }
        b>>=1;
        a=(a+a)%mo;
    }
    return ans;
}
long long poww(long long a,long long x)
{
    long long ans=1;
    a%=mo;
    while(x)
    {
        if(x&1)
        {
            ans=mul(ans,a);
        }
        x>>=1;
        a=mul(a,a);
    }
    return ans%mo;
}
int main()
{
    int t;
    int len;
    long long p;
    long long ans;
    cin>>t;
    while(t--)
    {
        ans=0;
        scanf("%s",&n);
        p=mo-1;
        len=strlen(n);
        if(len<=15)
        {
            for(int i=0;i<len;i++)
                ans=ans*10+n[i]-'0';
            ans--;
        }
        else
        {
            for(int i=0;i<len;i++)
            {
                ans=ans*10+n[i]-'0';
                ans%=p;
            }
            ans--;
            ans+=p;
            ans%=p;
            ans+=p;
        }
        printf("%lld\n",poww(2,ans));
    }
} 

H

I

import java.util.*; 

public class Main {

    static Scanner sc = new Scanner(System.in);

    public static void main(String[] args) {

        while(sc.hasNext()){
            int a = sc.nextInt(), b = sc.nextInt(), c = sc.nextInt();
            if(a*b*c%2==0)
                System.out.println("Yes");
            else
                System.out.println("No");
        }

    }

}

J

K 分組揹包的簡單變形

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int mo=1e9+7;
int n,q;
int dp[10100];
int main()
{
    int t;
    int n,q;
    int s;
    int v,c;
    scanf("%d",&t);
    int k;
    while(t--)
    {
        memset(dp,0,sizeof(dp));
        dp[0]=1;
        scanf("%d%d",&n,&q);
        while(n--)
        {
            scanf("%d%d",&v,&c);
            for(int i=0;i<c;i++)
            {
                k=(1<<i)*v;
                for(int j=10000;j>=k;j--)
                {
                    dp[j]+=dp[j-k];
                    dp[j]%=mo;
                }
            }
        }
        while(q--)
        {
            scanf("%d",&s);
            printf("%d\n",dp[s]);
        }
    }
    return 0;
}

L 矩陣快速冪,由數位DP的思想很容易就能找出遞推式

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1000000007;
struct node{
    ll mat[15][15];
};
ll n,m;
node mul(node x,node y)
{
    node z;
    for(int i=1;i<=9;i++)
    {
        for(int j=1;j<=9;j++)
        {
            z.mat[i][j]=0;
            for(int k=1;k<=9;k++)
            {
                z.mat[i][j]=(z.mat[i][j]+x.mat[i][k]*y.mat[k][j])%mod;
            }
        }
    }
    return z;
}
void solve()
{
    node ans,a;
    for(int i=1;i<=9;i++)
    {
        for(int j=1;j<=9;j++)
        {
            if(i==j) ans.mat[i][j]=1;
            else ans.mat[i][j]=0;
            a.mat[i][j]=0;
        }
    }
    a.mat[1][4]=a.mat[1][7]=a.mat[2][1]=a.mat[2][4]=a.mat[2][7]=a.mat[3][1]=a.mat[3][4]=a.mat[4][2]=a.mat[4][5]=a.mat[4][8]=1;
    a.mat[5][2]=a.mat[5][8]=a.mat[6][2]=a.mat[6][5]=a.mat[7][3]=a.mat[7][9]=a.mat[8][6]=a.mat[8][9]=a.mat[9][3]=a.mat[9][6]=1;
    while(m)
    {
        if(m&1) ans=mul(ans,a);
        m>>=1;
        a=mul(a,a);
    }
    ll res=0;
    for(int i=1;i<=9;i++)
    {
        for(int j=1;j<=9;j++)
        {
            res+=ans.mat[i][j];
            res%=mod;
        }
    }
    printf("%lld\n",res);
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld",&n);
        if(n==1) printf("3\n");
        else if(n==2) printf("9\n");
        else
        {
            m=n-2;
            solve();
        }
    }
    return 0;
}