2017"百度之星"程序设计大赛 - 复赛

1001.Arithmetic of Bomb

直接模拟求出最后的串就好了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <string>
using namespace std;

char s[1005];
long long ans = 0;
const int mod = 1000000007;
struct Node
{
    char s[1005];
    int cnt;
};
Node gao2(int &pos)
{
    pos--;
    Node temp;
    temp.cnt = s[pos] - '0';
    pos--;
    while (s[pos] < '0' || s[pos] > '9') pos--;
    int t = 0;
    for (; s[pos] != '('; pos--){
        temp.s[t++] = s[pos];
    }
    temp.s[t] = 0;
    return temp;
}

void gao(long long x)
{
    x %= mod;
    ans = ans + x;
    ans %= mod;
}
int main()
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        scanf("%s", s);
        int len = strlen(s);
        ans = 0;
        long long pre = 1;
        for (int i = len - 1; i >= 0; i--){
            if (s[i] == ')'){
                Node now = gao2(i);
                while (now.cnt--){
                    int len1 = strlen(now.s);
                    for (int j = 0; j < len1; j++){
                        gao((now.s[j] - '0') * pre);
                        pre *= 10;
                        pre %= mod;
                    }
                }
            }
            else{
                gao((s[i] - '0') * pre);
                pre *= 10;
                pre %= mod;
            }

        }
        printf("%I64d\n", ans);
    }
}

1003.Pokémon GO

解法1:dp
解法2:找规律。。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <string>
using namespace std;
const long long mod = 1e9 + 7;
//long long biao[] = { 1, 6, 12, 26, 48, 86, 148, 250, 416, 686, 1124, 1834, 2984, 4846, 7860, 12738, 20632, 33406, 54076, 87522, 141640, 229206, 370892, 600146, 971088, 1571286, 2542428, 4113770, 6656256, 10770086, 17426404, 28196554, 45623024, 73819646, 119442740, 193262458 };
long long qpow(long long x, long long a) {
    long long ret = 1;
    while (a) {
        if (a & 1) ret = (ret*x) % mod;
        x = (x*x) % mod;
        a >>= 1;
    }
    return ret;
}
long long num[11000];
int main()
{
    num[0] = 1;
    num[1] = 1;
    num[2] = 6;
    num[3] = 12;
    for (int i = 4; i <= 10000; i++) {
        num[i] = 
         (( ( ( ( (8 * i - 31) * num[i - 1] % mod + mod ) % mod - (4 * i - 19) * num[i - 2] % mod + mod) % mod ) - (3 * i - 10) * num[i - 3] % mod + mod) % mod + (2 * i - 10) * num[i - 4] + mod) % mod * qpow(3 * i - 11, mod - 2) % mod;
    }
    int T;
    cin >> T;
    while (T--) {
        long long N;
        cin >> N;
        long long ans = num[N] * qpow(2, N) % mod;
        cout << ans << endl;
    }
}

1005.Valley Numer

数位dp。
dp[p][pre][isdown][lim][st]表示进行到第p位,前一位是pre,是否是下降的,是否有限制,是否之前都是前导0时的种类数。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <string>
using namespace std;
const long long MOD = 1e9 + 7;
long long dp[110][11][2][2][2];
int len, num[110];
char str[110];
long long dfs(int p, int pre, int isdown, int lim, int st)
{
    if (p == len + 1)return !st;
    if (dp[p][pre][isdown][lim][st] != -1 && !lim)return dp[p][pre][isdown][lim][st];
    long long temp = 0;
    int r = lim ? num[p] : 9;
    for (int i = 0; i <= r; i++)
    {
        if (isdown) 
        {
            if (i > pre) {
                temp += dfs(p + 1, i, 0, lim&&i == r, 0) % MOD;
            }
            else {
                if (st && i == 0) {
                    temp += dfs(p + 1, 10, 1, lim&&i == r, st) % MOD;
                }
                else {
                    temp += dfs(p + 1, i, 1, lim&&i == r, 0) % MOD;
                }

            }
        }
        else if (i >= pre) {
            temp += dfs(p + 1, i, 0, lim&&i == r, 0) % MOD;
        }
        temp = temp % MOD;
    }
    return dp[p][pre][isdown][lim][st] = temp % MOD;
}

int main()
{
    int T;
    scanf("%d\n", &T);
    while (T--)
    {
        scanf("%s", str);
        len = strlen(str);
        for (int i = 0; i<len; i++)
            num[i + 1] = str[i] - '0';
        memset(dp, -1, sizeof(dp));
        printf("%I64d\n", dfs(1, 10, 1, 1, 1));
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值