C. Torn Lucky Ticket

纯粹的發表於2024-04-27

原題連結

題解

1.題目對 \(i,j\) 沒有限制,也就是說,i可以大於j,可以小於j,也可以等於j
2.找普適規律。不管誰和誰成功配對,要麼兩個數長度相等;要麼前面的數長度大於後面的數,於是前面的數分後半部分出來;要麼後面的數大於前面的數,於是後面的數分前半部分出來;

code

#include<bits/stdc++.h>
#define ll long long
using namespace std;

ll ten[7];
ll a[200005];
int main()
{
    ten[0]=1;
    for(ll i=1;i<=6;i++) ten[i]=ten[i-1]*10;

    ll n;
    cin>>n;
    ll ans=0;
    for(ll i=1;i<=n;i++) cin>>a[i];
    sort(a+1,a+1+n);


    map<ll,ll> dp[7];
    for(ll i=1;i<=n;i++)
    {
        ll x=a[i];
        ll sum=0,len=0,tem=x;
        while(tem)
        {
            sum+=tem%10;
            len++;
            tem/=10;
        }

        ans+=dp[len][sum]*2;//左右呼喚

        ll pre=0;
        for(ll j=len;j>=len/2+2;j--)//後面的數分前半部分出來
        {
            pre=pre+x/ten[j-1]%10;//是數字之和不是數字擷取
            ans+=dp[(j-1)-(len-(j-1))][sum-pre-pre];
        }

        pre=0;
        for(ll j=1;j<=len/2-(1-len%2);j++)//前面的數分後半部分出來
        {
            pre=pre+x/ten[j-1]%10;
            ans+=dp[len-j-j][sum-pre-pre];
        }

        dp[len][sum]++;
    }


    cout<<ans+n;
    return 0;
}

相關文章