算法学社 -- "这是一道难题"第二期

算法学社 -- "这是一道难题"第二期

针对算法学社新生的一套有奖答题,共9题,分为三个系列,系列内三题的数据难度依次递增。

比赛地址

A、B 光棍节系列

题解:

简单题

#include 
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define EPS 1e-6
#define N 1123456
using namespace std;
int n,m,res,flag;
int main()
{
    int i,j,k,kk,cas,T,x,y,z;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        long long sum=0,t=1;
        while(n)
        {
            sum+=(n/10*t);
            if(n%10>1)sum+=t;
            else if(n%10==1)sum+=(m%t+1);
            t*=10;
            n/=10;
        }
        printf("%lld\n",sum);
    }
    return 0;
}



C、D、E 括号匹配系列

题解:

简单DP

#include 
#define LL long long
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define EPS 1e-6
#define N 112345
using namespace std;
LL n,m,sum,res,flag;
char s[N];
LL dp[2002][2002];
int main()
{
    LL i,j,k,kk,cas,T,t,x,y,z;
    z=0;
    while(scanf("%I64d%I64d",&n,&m)!=EOF)
    {
        scanf("%s",s);
        if(z)printf("\n");
        z=1;
        memset(dp,0,sizeof(dp));
        for(dp[0][0]=1,i=1;i<=n-m;i++)
            for(j=0;j<=i;j++)
                dp[i][j]=(dp[i-1][j+1]+(j>0?dp[i-1][j-1]:0))%MOD;
        x=y=0;res=0;
        for(i=0;i=0)res=(res+dp[i][j]*dp[n-m-i][j+x]%MOD)%MOD;
        printf("%I64d",res);
    }
    return 0;
}




F、G、H  LCS系列

题解:

最长公共子串经典题,F暴力就行,G要dp,H可以套后缀自动机水过

F:

#include 
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define EPS 1e-6
#define N 1123456
using namespace std;
int n,m,sum,res,flag;
char s[N],ss[N];
int main()
{
    int i,j,k,kk,cas,T,t,x,y,z;
    while(scanf("%s",s)!=EOF)
    {
        scanf("%s",ss);
        n=strlen(s);
        m=strlen(ss);
        res=0;
        for(k=-m;k<=n;k++)
        {
            t=0;j=0;i=j+k;
            if(i<0)j=-i,i=0;
            for(;i


G:

#include 
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define EPS 1e-6
#define N 1123
using namespace std;
int n,m,sum,res,flag;
char s[N],ss[N];
int dp[N][N];
int LCS(char *a, char *b)
{
	memset(dp,0,sizeof(dp));
	int x=strlen(a),y=strlen(b);
	for(int i = 1; i <= x; i++)
		for(int j = 1; j <= y; j++)
        {
			if(a[i-1] == b[j-1])
                dp[i][j] = dp[i-1][j-1] + 1;
            else
                dp[i][j] = max(dp[i][j-1],dp[i-1][j]);
		}
    return dp[x][y];
}
int main()
{
    int i,j,k,kk,cas,T,t,x,y,z;
    while(scanf("%s",s)!=EOF)
    {
        scanf("%s",ss);
        printf("%d\n",LCS(s,ss));
    }
    return 0;
}


H:

#include 
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define EPS 1e-6
#define N 1123456
using namespace std;
struct SAM
{
    struct Node
    {
        int ch[26];
        int f, len;
        void init()
        {
            f = -1, len = 0;
            memset(ch, 0xff, sizeof (ch));
        }
    };
    Node sn[N<<1];
    int idx, last;
    void init()
    {
        idx = last = 0;
        sn[idx++].init();
    }
    int newnode()
    {
        sn[idx].init();
        return idx++;
    }
    void add(int c)
    {
        int end = newnode();
        int tmp = last;
        sn[end].len = sn[last].len + 1;
        for ( ; tmp != -1 && sn[tmp].ch[c] == -1; tmp = sn[tmp].f)
            sn[tmp].ch[c] = end;
        if (tmp == -1) sn[end].f = 0;
        else
        {
            int nxt = sn[tmp].ch[c];
            if (sn[tmp].len + 1 == sn[nxt].len) sn[end].f = nxt;
            else
            {
                int np = newnode();
                sn[np] = sn[nxt];
                sn[np].len = sn[tmp].len + 1;
                sn[end].f = sn[nxt].f = np;
                for (; tmp != -1 && sn[tmp].ch[c] == nxt; tmp = sn[tmp].f)
                    sn[tmp].ch[c] = np;
            }
        }
        last = end;
    }
};
SAM sam;

int n,m,sum,res,flag;
char s[N];
int main()
{
    int i,j,k,kk,cas,T,t,x,y,z;
    while(scanf("%s",s)!=EOF)
    {
        sam.init();
        n=strlen(s);
        for(i=0;i




你可能感兴趣的:(套题)