记录编号 243517 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [国家集训队2011]Digit 最终得分 100
用户昵称 Gravatarmikumikumi 是否通过 通过
代码语言 C++ 运行时间 2.689 s
提交时间 2016-03-30 09:17:32 内存使用 126.67 MiB
显示代码纯文本
  1. #include<cstdio>
  2. #include<iostream>
  3. #include<string>
  4. #include<deque>
  5. #include<cstring>
  6. #include <sstream>
  7. using namespace std;
  8. const int MAXN=910;
  9. int d,s1,s2;
  10. int n;
  11. class miku
  12. {
  13. public:
  14. int s1,s2,r;
  15. void print()
  16. {
  17. cout<<s1<<" "<<s2<<" "<<r<<endl;
  18. }
  19. };
  20. deque<miku> Q;
  21. int Len[MAXN*2][MAXN*2][10];//A的位数和为i,A*D除第n+1外位数和为j,A*D的第n+1位为k,A的最少位数
  22. void prepare()
  23. {
  24. memset(Len,0x7F,sizeof(Len));
  25. miku tem;
  26. for(int i=0;i<10;i++)
  27. {
  28. tem.s1=i;
  29. tem.s2=i*d%10;
  30. tem.r=i*d/10;
  31. Q.push_back(tem);
  32. Len[tem.s1][tem.s2][tem.r]=1;
  33. }
  34. Len[0][0][0]=0;
  35. while(!Q.empty())
  36. {
  37. miku S=Q.front();Q.pop_front();
  38. for(int i=0;i<=9;i++)
  39. {
  40. tem.s1=S.s1+i;
  41. tem.s2=S.s2+(S.r+i*d)%10;
  42. tem.r=(S.r+i*d)/10;
  43. //tem.print();
  44. if(tem.s1>s1||tem.s2>s2) continue;
  45. if(Len[tem.s1][tem.s2][tem.r]>Len[S.s1][S.s2][S.r]+1)
  46. {
  47. Len[tem.s1][tem.s2][tem.r]=Len[S.s1][S.s2][S.r]+1;
  48. Q.push_back(tem);
  49. }
  50. }
  51. }
  52. }
  53. void get(ostringstream &oss,int len,int S1,int S2,int R)
  54. {
  55. for(int i=0;i<len;i++)
  56. {
  57. bool ok=0;
  58. for(int j=0;j<=9;j++)
  59. {
  60. for(int k=0;k<=9;k++)
  61. {
  62. int ns1=S1-j,ns2=S2-k;
  63. int nr=R*10-j*d+k;
  64. if(nr<0||nr>9) continue;
  65. if(ns1<0||ns2<0)continue;
  66. if(Len[ns1][ns2][nr]>len-i-1)continue;
  67. S1=ns1,S2=ns2,R=nr;
  68. //cout<<i<<endl;
  69. oss<<j;
  70. ok=1;
  71. break;
  72. }
  73. if(ok==1) break;
  74. }
  75. if (ok==0)
  76. {
  77. for(int j=i;j<len;j++) oss<<"0";
  78. return;
  79. }
  80. }
  81. }
  82. int getsum(int x)
  83. {
  84. int re=0;
  85. while(x)
  86. {
  87. re+=x%10;
  88. x/=10;
  89. }
  90. return re;
  91. }
  92. string ans;
  93. void Calc(int i,ostringstream &tem)
  94. {
  95. string now=tem.str();
  96. //cout<<now<<endl;
  97. ostringstream tem2;
  98. tem2<<i;
  99. for(int u=0;u<n-now.length()-1;u++) tem2<<"0";
  100. tem2<<now;
  101. now=tem2.str();
  102. if(now.size()<ans.size()||(now.size()==ans.size()&&now<ans)) ans=now;
  103. }
  104. void work()
  105. {
  106. ans="";
  107. for(int i=0;i<=MAXN+1;i++) ans+="9";
  108. //cout<<ans<<endl;
  109. for(int i=1;i<=9;i++)//枚举首位,因为不能有前导0
  110. {
  111. int ns=s1-i;
  112. if(ns<0) continue;
  113. for(int j=0;j<=9;j++)
  114. {
  115. for(int k=0;k<=s2;k++)
  116. {
  117. if(Len[ns][k][j]>n-1) continue;
  118. if(k+getsum(j+i*d)==s2)
  119. {
  120. ostringstream tem;
  121. //cout<<ns<<" "<<k<<" "<<j<<" "<<Len[ns][k][j]<<endl;
  122. get(tem,n-1,ns,k,j);
  123. Calc(i,tem);
  124. }
  125. if(Len[ns][k][j]<n-1&&k+j+getsum(i*d)==s2)
  126. {
  127. ostringstream tem;
  128. //cout<<ns<<" "<<k<<" "<<j<<" "<<Len[ns][k][j]<<endl;
  129. get(tem,Len[ns][k][j],ns,k,j);
  130. Calc(i,tem);
  131. }
  132. }
  133. }
  134. }
  135. if(ans.size()>MAXN) printf("-1\n");
  136. else cout<<ans<<endl;
  137. }
  138. int main()
  139. {
  140. freopen("nt2011_digit.in","r",stdin);
  141. freopen("nt2011_digit.out","w",stdout);
  142. scanf("%d%d%d%d",&n,&s1,&s2,&d);
  143. prepare();
  144. work();
  145. //cout<<Len[9][9][0]<<endl;
  146. return 0;
  147. }