zoukankan      html  css  js  c++  java
  • [atARC075F]Mirrored

    假设$n=sum_{i=0}^{k}a_{i}10^{i}$(其中$a_{k}>0$),则有$d=f(n)-n=sum_{i=0}^{k}(10^{k-i}-10^{i})a_{i}$,考虑$i$和$k-i$,不难化简得到$d=sum_{i=0}^{lfloorfrac{k-1}{2} floor}(10^{k-i}-10^{i})(a_{i}-a_{k-i})$

    (这里忽略了当$k$为偶数时$a_{frac{k}{2}}$,因为其系数为0,因此当$k$为偶数时答案可以再乘10)

    记$b_{i}=a_{i}-a_{k-i}$后,考虑去统计$b_{i}$,之后再加上对应的$a_{i}$,即$prod(10-|b_{i}|)$种

    从0到$lfloorfrac{k-1}{2} floor$依次确定$b_{i}$,当要确定$b_{i}$时(即$b_{0..i-1}$都已经确定),考虑$b_{i}$之后的位置所能产生的贡献,不难得到$b_{i}$合法的必要条件为$|d-sum_{j=0}^{i}(10^{k-j}-10^{j})b_{j}|le 9sum_{j=i+1}^{lfloorfrac{k-1}{2} floor}(10^{k-j}-10^{j})$

    又因为$10^{k-i}-10^{i}>9sum_{j=i+1}^{lfloorfrac{k-1}{2} floor}(10^{k-j}-10^{j})$,即当左边绝对值内已经是正数时,再增加$b_{i}$一定不合法,类似的负数时不能减少,因此$b_{i}$最多只有两种(恰好为正数或负数)

    如果爆搜,对于每一个$k$都有$2^{lfloorfrac{k-1}{2} floor}$的复杂度,因此考虑确定$k$的范围:

    对于$10^{k-i}-10^{i}>9sum_{j=i+1}^{lfloorfrac{k-1}{2} floor}(10^{k-j}-10^{j})$这个条件,更精确的,我们在右边再加上$10^{lceilfrac{k+1}{2} ceil}$后也是正确的,即$10^{k-i}-10^{i}>9sum_{j=i+1}^{lfloorfrac{k}{2} floor}(10^{k-j}-10^{j})+10^{lceilfrac{k+1}{2} ceil}$

    接下来证明若$dle 10^{lceilfrac{k+1}{2} ceil}-10^{lfloorfrac{k-1}{2} floor}$,一定无解——

    归纳$b_{i}=0$,即当确定$b_{i}$时$b_{0..i-1}=0$,此时来证明$b_{i}=0$

    由于$d>0$,因此$b_{i}le 1$,同时$b_{i}$的系数最小即为$10^{lceilfrac{k+1}{2} ceil}-10^{lfloorfrac{k-1}{2} floor}$,因此$b_{i}ge -1$

    而当$b_{i}=-1$时,$(10^{k-j}-10^{j})-d>9sum_{j=i+1}^{lfloorfrac{k}{2} floor}(10^{k-j}-10^{j})+10^{lceilfrac{k+1}{2} ceil}-10^{lceilfrac{k+1}{2} ceil}$(第一项$10^{lceilfrac{k+1}{2} ceil}$是更精确的比较,第二项是$d<10^{lceilfrac{k+1}{2} ceil}$),因此即不满足必要条件

    当所有$b_{i}=0$时,不难得到$d=0$,即无解,因此有$kle 18$,总复杂度即为$o(18cdot 2^{9})$,可以通过

    有1个细节:要求$a_{k}>0$,因此若$b_{0}ge 0$则$b_{0}$的对$a_{i}$贡献系数为$9-b_{0}$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 21
     4 #define ll long long
     5 ll n,sum,ans,mi[N];
     6 void dfs(int k,int t,ll n,ll tot){
     7     if (k>(t-1)/2){
     8         if (!n)sum+=tot;
     9         return;
    10     }
    11     ll s=mi[t-k]-mi[k];
    12     n+=9*s;
    13     for(int i=-9;i<=9;i++){
    14         if (abs(n)<s)dfs(k+1,t,n,tot*(10-abs(i)-((!k)&&(i>=0))));
    15         n-=s;
    16     }
    17 }
    18 int main(){
    19     scanf("%lld",&n);
    20     mi[0]=1;
    21     for(int i=1;i<=18;i++)mi[i]=mi[i-1]*10;
    22     for(int i=1;i<=18;i++){
    23         sum=0;
    24         dfs(0,i,n,1);
    25         if (i%2==0)sum*=10;
    26         ans+=sum;
    27     }
    28     printf("%lld",ans);
    29 } 
    View Code
  • 相关阅读:
    PAT (Advanced Level) Practice 1055 The World's Richest (25 分) (结构体排序)
    PAT (Advanced Level) Practice 1036 Boys vs Girls (25 分)
    PAT (Advanced Level) Practice 1028 List Sorting (25 分) (自定义排序)
    PAT (Advanced Level) Practice 1035 Password (20 分)
    PAT (Advanced Level) Practice 1019 General Palindromic Number (20 分) (进制转换,回文数)
    PAT (Advanced Level) Practice 1120 Friend Numbers (20 分) (set)
    从零开始吧
    Python GUI编程(TKinter)(简易计算器)
    PAT 基础编程题目集 6-7 统计某类完全平方数 (20 分)
    PAT (Advanced Level) Practice 1152 Google Recruitment (20 分)
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/14252100.html
Copyright © 2011-2022 走看看