2017"百度之星"程序設計大賽 - 複賽(1001,1003,1005)

Arithmetic of Bomb Accepts: 1050 Submissions: 1762
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Problem Description
衆所周知,度度熊非常喜歡數字。
它最近在學習小學算術,第一次發現這個世界上居然存在兩位數,三位數……甚至N位數!
但是這回的算術題可並不簡單,由於含有表示bomb的#號,度度熊稱之爲 Arithmetic of Bomb。
Bomb Number中的bomb,也就是#號,會展開一些數字,這會導致最終展開的數字超出了度度熊所能理解的範疇。比如”(1)#(3)”表示”1”出現了3次,將會被展開爲”111”,
同理,”(12)#(2)4(2)#(3)”將會被展開爲”12124222”。
爲了方便理解,下面給出了Bomb Number的BNF表示。
請將Bomb Number中所有的#號展開,由於數字可能很長,結果對 1 000 000 007 取模。
Input
第一行爲T,表示輸入數據組數。
每組數據包含一個Bomb Expression。
1≤T≤100
1≤length(Bomb Number)≤1000
Output
對每組數據輸出表達式的結果,結果對 1 000 000 007 取模。
Sample Input
4
1
(1)#(3)
(12)#(2)4(2)#(3)
(12)#(5)
Sample Output
1
111
12124222
212121205
題解:模擬就行了。。。
代碼:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
#include<queue>
#include<set>
#include<algorithm>
#include<map>
#include<math.h>
using namespace std;
typedef long long int ll;
typedef pair<int,int>pa;
const int N=1e5+100;
const int mod=1e9+7;
const ll INF=1e18;
int read()
{
    int x=0;
    char ch = getchar();
    while('0'>ch||ch>'9')ch=getchar();
    while('0'<=ch&&ch<='9')
    {
        x=(x<<3)+(x<<1)+ch-'0';
        ch=getchar();
    }
    return x;
}
/***********************************************************/
int t;
char str[10000];
string ans,zhi;
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        int cnt=0;
        scanf("%s",str);
        int sz=strlen(str);
        ll c=0;
        bool flag=false;
        ans.clear();
        for(int i=0; i<sz; i++)
        {
            if(str[i]=='(')
            {
                if(flag)
                {
                    int j=i;
                    while(str[++j]!=')')
                    {
                        c=c*10+str[j]-'0';
                    }
                    i=j;
                    for(ll k=1;k<=c;k++)
                    {
                        ans+=zhi;
                    }
                    zhi.clear();
                    c=0;
                    flag=false;
                }
                else
                {
                    int j=i;
                    while(str[++j]!=')')
                    {
                       zhi+=str[j];
                    }
                    i=j;
                }
            }
            else if(str[i]=='#')
            {
                flag=true;
            }
            else
            {
                ans+=str[i];
            }
        }
        int l=ans.length();
        ll ok=0;
        for(int i=0;i<l;i++)
        {
            ok=(ok*10+ans[i]-'0')%mod;
        }
        printf("%I64d\n",ok);
    }
}

Pokémon GO Accepts: 738 Submissions: 1725
Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Problem Description
衆所周知,度度熊最近沉迷於 Pokémon GO。

今天它決定要抓住所有的精靈球!

爲了不讓度度熊失望,精靈球已經被事先放置在一個2*N的格子上,每一個格子上都有一個精靈球。度度熊可以選擇任意一個格子開始遊戲,抓捕格子上的精靈球,然後移動到一個相鄰的至少有一個公共點的格子上繼續抓捕。例如,(2, 2) 的相鄰格子有(1, 1), (2, 1) 和 (1, 2) 等等。

現在度度熊希望知道將所有精靈球都抓到並且步數最少的方案數目。兩個方案被認爲是不同,當且僅當兩個方案至少有一步所在的格子是不同的。

Input
第一行爲T,表示輸入數據組數。

每組數據包含一個數N。

●1≤T≤100

●1≤N≤10000

Output
對每組數據輸出方案數目,結果對 1 000 000 007 取模。

Sample Input
3
1
2
3
Sample Output
Copy
2
24
96
題解:原題。
代碼:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
#include<queue>
#include<set>
#include<algorithm>
#include<map>
#include<math.h>
using namespace std;
typedef long long int ll;
typedef pair<int,int>pa;
const int N=1e5+100;
const int mod=1e9+7;
const ll INF=1e18;
int read()
{
    int x=0;
    char ch = getchar();
    while('0'>ch||ch>'9')ch=getchar();
    while('0'<=ch&&ch<='9')
    {
        x=(x<<3)+(x<<1)+ch-'0';
        ch=getchar();
    }
    return x;
}
/***********************************************************/
ll a[N];
ll b[N];
ll c;
int n,t;
void init()
{
    b[1]=1;
    for (int i=2; i<=10000; i++)
    {
        b[i]=(b[i-1]*2%mod);
        b[i]%=mod;
    }
    a[1]=1;
    a[2]=6;
    for (int i=3; i<=10000; i++)
    {
        a[i]=(2*a[i-1]+b[i]+4*a[i-2])%mod;
    }
}
void slove()
{
    c=4*a[n];
    for (int i=2; i<n; i++)
    {
        c=(c+(8*b[n-i]*a[i-1]%mod)%mod+(8*a[n-i]*b[i-1])%mod)%mod;
    }
    printf("%I64d\n",c);
}
int main()
{
    init();
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        if(n==1) puts("2");
        else slove();
    }
    return 0;
}

Valley Numer Accepts: 548 Submissions: 1125
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Problem Description
衆所周知,度度熊非常喜歡數字。

它最近發明了一種新的數字:Valley Number,像山谷一樣的數字。

當一個數字,從左到右依次看過去數字沒有出現先遞增接着遞減的“山峯”現象,就被稱作 Valley Number。它可以遞增,也可以遞減,還可以先遞減再遞增。在遞增或遞減的過程中可以出現相等的情況。

比如,1,10,12,212,32122都是 Valley Number。

121,12331,21212則不是。

度度熊想知道不大於N的Valley Number數有多少。

注意,前導0是不合法的。

Input
第一行爲T,表示輸入數據組數。

每組數據包含一個數N。

● 1≤T≤200

● 1≤length(N)≤100

Output
對每組數據輸出不大於N的Valley Number個數,結果對 1 000 000 007 取模。

Sample Input
3
3
14
120
Sample Output
Copy
3
14
119
題解:數位dp,設dp[i][j][k]表示當前位,前一位爲j,前面是否爲遞增。
然後轉移一下就行。
代碼:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
#include<queue>
#include<set>
#include<algorithm>
#include<map>
#include<math.h>
using namespace std;
typedef long long int ll;
typedef pair<int,int>pa;
const int N=1e5+100;
const int mod=1e9+7;
const ll INF=1e18;
int read()
{
    int x=0;
    char ch = getchar();
    while('0'>ch||ch>'9')ch=getchar();
    while('0'<=ch&&ch<='9')
    {
        x=(x<<3)+(x<<1)+ch-'0';
        ch=getchar();
    }
    return x;
}
/***********************************************************/
int t;
char str[110];
int a[110];
ll dp[110][11][2];
ll dfs(int pos,int zhi,int sta ,bool limit,bool lead)
{
    if(pos==-1) return 1;
    if(!limit&&dp[pos][zhi][sta]!=-1&&!lead)
    return dp[pos][zhi][sta];
    ll ans=0;
    int up=limit?a[pos]:9;
    for(int i=0;i<=up;i++)
    {
        if(lead)
        {
            if(i==0)
                ans+=dfs(pos-1,0,0,limit&&i==a[pos],true);
            else
                ans+=dfs(pos-1,i,0,limit&&i==a[pos],false);
        }
        else
        {
            if(sta==1)
            {
                if(i>=zhi)
                    ans+=dfs(pos-1,i,1,limit&&i==a[pos],false);
            }
            else
            {
                ans+=dfs(pos-1,i,i>zhi,limit&&i==a[pos],false);
            }
        }
    }
    ans=ans%mod;
    if(!limit&&!lead)
    dp[pos][zhi][sta]=ans;
        return ans;
}
ll solve()
{
    int pos=0;
    int sz=strlen(str);
    for(int i=sz-1;i>=0;i--)
    {
        a[pos++]=str[i]-'0';
    }
    return dfs(pos-1,0,0,true,true)%mod;
}
int main()
{
    scanf("%d",&t);
    memset(dp,-1,sizeof(dp));
    while(t--)
    {
        scanf("%s",str);
        printf("%I64d\n",(solve()-1+mod)%mod);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章