zoukankan      html  css  js  c++  java
  • JZOJ 3056. 【NOIP2012模拟10.27】数字

    题目

    Description

    【问题描述】


        一个数字被称为好数字当他满足下列条件:


    1. 它有2*n个数位,n是正整数(允许有前导0)   


    2. 构成它的每个数字都在给定的数字集合S中。


        3. 它前n位之和与后n位之和相等或者它奇数位之和与偶数位之和相等


        例如对于n=2,S={1,2},合法的好数字有1111,1122,1212,1221,2112,2121,2211,2222这样8种。


    已知n,求合法的好数字的个数mod 999983。


     

    Input

        第一行一个数n。


        接下来一个长度不超过10的字符串,表示给定的数字集合。


    Output

        一行一个数字表示合法的好数字的个数mod 999983。


     

    Sample Input

    2
    0987654321
    

    Sample Output

    1240
     

    Data Constraint

     
     

    Hint

        对于20%的数据,n≤7。


        对于100%的.据,n≤1000,|S|≤10。

     

    分析

    •  答案其实是

    •  前n位之和与后n位之和相等+它奇数位之和与偶数位之和相等-两个都有的
    •  前两种很好求,递推就好了
    •  第三种其实就是 

       因为前n位之和=后n位之和,奇数位之和=偶数位之和

       所以前n位中奇数位之和=后n位中偶数位之和 且

       前n位中偶数位之和=后n位中奇数位之和

     

    代码

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<vector>
     8 #define mod 999983
     9 #define ll long long
    10 using namespace std;
    11 inline ll read()
    12 {
    13     ll x=0,f=1;char ch=getchar();
    14     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    15     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    16     return x*f;
    17 }
    18 int n;
    19 char ch[15];
    20 int a[15];
    21 int f[1005][9005];
    22 ll ans;
    23 ll cal(int x)
    24 {
    25     ll ans=0;
    26     for(int i=0;i<=x*9;i++)
    27         if(f[x][i])
    28             ans=(ans+((ll)f[x][i]*f[x][i]))%mod;
    29     return ans;
    30 }
    31 int main()
    32 {
    33     n=read();
    34     scanf("%s",ch);
    35     int l=strlen(ch);
    36     for(int i=0;i<l;i++)
    37         a[i+1]=ch[i]-'0';
    38     f[0][0]=1;
    39     for(int i=0;i<n;i++)
    40         for(int j=0;j<=n*9;j++)
    41             if(f[i][j])
    42                 for(int k=1;k<=l;k++)
    43                     f[i+1][j+a[k]]=(f[i+1][j+a[k]]+f[i][j])%mod;
    44     ans=2*cal(n)-cal(n/2)*cal(n-n/2);
    45     printf("%d",(ans%mod+mod)%mod);
    46     return 0;
    47 }
    为何要逼自己长大,去闯不该闯的荒唐
  • 相关阅读:
    web 后台返回json格式数据的方式(status 406)
    消息队列比较
    CAP
    Redis分布式锁的正确实现方式
    idea 快捷键
    给web请求加遮罩动画
    java动态代理实现与原理详细分析(代码层面解释了AOP的实现)
    Spring框架IOC和AOP的实现原理(概念)
    springboot后台控制重定向
    消息队列如何保证幂等性?
  • 原文地址:https://www.cnblogs.com/zjzjzj/p/10500574.html
Copyright © 2011-2022 走看看