ACM-ICPC 2018 焦作赛区网络预赛 题解

A

#include
#include
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!"<else
            cout<<"Dare you say that again?"<

B
dp[i][j][0]表示使用了前i个符号,以第j个数字结尾 的最大值
dp[i][j][1]表示使用了前i个符号,以第j个数字结尾 的最小值

#include
#include
#include
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;iscanf("%lld",&a[i]);
        }
        getchar();
        scanf("%s",s);
        len=strlen(s);
        for(int i=0;ifor(int j=0;j0]=-inf;
                dp[i][j][1]=inf;
            }
        maxx=k;
        minn=k;
        int tj=0;
        for(int i=0;iif(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;jif(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;j1][j][0]);
        printf("%lld\n",maxx);
    }
}

C

D

E

F

G
指数循环节+快速幂

#include
#include
#include
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;i10+n[i]-'0';
            ans--;
        }
        else
        {
            for(int i=0;i10+n[i]-'0';
                ans%=p;
            }
            ans--;
            ans+=p;
            ans%=p;
            ans+=p;
        }
        printf("%lld\n",poww(2,ans));
    }
} 

H
后缀自动机(SAM)模板题

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
套个JAVA大数开方的板子就OK了

import java.math.BigInteger;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner cin=new Scanner(System.in);
        int t=cin.nextInt();
        while(t-->0) {
            String str=cin.next();
            BigInteger n=new BigInteger(str);
            BigInteger m=n.multiply(n.subtract(BigInteger.ONE)).shiftRight(1);
            boolean ni=isSquare(n),mi=isSquare(m);
            if(ni&&mi)
                System.out.println("Arena of Valor");
            else if(ni&&!mi)
                System.out.println("Hearth Stone");
            else if(!ni&&mi)
                System.out.println("Clash Royale");
            else
                System.out.println("League of Legends");
        }
        cin.close();
    }
    public static boolean isSquare(BigInteger n) {
        BigInteger l=BigInteger.ZERO,r=n,mid,ans;
        int res;
        while(l.compareTo(r)<=0) {
            mid=l.add(r).shiftRight(1);
            ans=mid.multiply(mid);
            res=ans.compareTo(n);
            if(res==0)
                return true;
            else if(res<0)
                l=mid.add(BigInteger.ONE);
            else
                r=mid.subtract(BigInteger.ONE);
        }   
        return false;
    }
}

K
分组背包的简单变形

#include
#include
#include
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;i1<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
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;
}

你可能感兴趣的:(ACM-ICPC 2018 焦作赛区网络预赛 题解)