zoukankan      html  css  js  c++  java
  • 【洛谷3896】[湖南集训] Clever Rabbit(搜索)

    点此看题面

    • 定义(g(x))表示将(x)各位数码从大到小排序后构成的数字,(h(x))表示将(x)各位数码从小到大排序后构成的数字。
    • 求所有满足(x=g(x)-h(x))(n)位数(x)的平方和。
    • (nle30)

    非打表的(dfs)做法

    显然这道题目(nle30)完全可以打表做,这里就不多说了。

    考虑在不借位(即每一位的数可以小于(0))的情况下肯定满足第(i)位与第(n-i+1)位互为相反数,且从高到低每一位降序。

    因此我们可以直接枚举一个长为(lfloorfrac n2 floor)的降序序列,先对它进行一轮借位操作求出(x),然后计算(g(x)-h(x))检验即可。

    代码:(O(nC_{lfloorfrac n2 floor+9}^9))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 30
    using namespace std;
    int n,ans,X,p[N+5],s[N+5],s1[N+5],s2[N+5];I void Check()
    {
    	RI i,j;for(i=1;i<=n;++i) s[i]=p[i];for(i=1;i<=n;++i) s[i]<0&&(s[i]+=10,--s[i+1]),s1[i]=s[i];//一轮借位还原出x
    	for(sort(s1+1,s1+n+1),i=1;i<=n;++i) s2[n-i+1]=s1[i];//求出g(x)和h(x)
    	for(i=1;i<=n;++i) if((s1[i]-=s2[i])<0&&(s1[i]+=10,--s1[i+1]),s1[i]^s[i]) return;//比较g(x)-h(x)与x
    	RI t=0;for(i=n;i;--i) t=(10LL*t+s[i])%X;ans=(ans+1LL*t*t)%X;//符合条件,统计答案
    }
    I void dfs(CI x=1,CI v=9)//枚举长为n/2的降序序列
    {
    	if(x>n/2) return Check();for(RI i=v;~i;--i) p[x]=-i,p[n-x+1]=i,dfs(x+1,i);
    }
    int main()
    {
    	return scanf("%d%d",&n,&X),dfs(),printf("%d
    ",ans),0;
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    2019.8.15刷题统计
    2019.8.12刷题统计
    2019.8.11刷题统计
    2019.8.10刷题统计
    2019.8.9刷题统计
    2019.8.8刷题统计
    2019.8.7刷题统计
    2019.8.6刷题统计
    xuezhan.org 6.28
    xuezhan.org 6.27
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu3896.html
Copyright © 2011-2022 走看看