[关闭]
@Moritz 2019-03-26T04:24:58.000000Z 字数 1623 阅读 467

第七届蓝桥杯C/C++A组省赛

蓝桥杯 编程 C++ 竞赛 所有文稿


7.剪邮票

DFS+全排列

  1. /*16:26*/
  2. /*16:52 输出296*/
  3. /*16:59 debug完成 输出116*/
  4. #include <iostream>
  5. #include <cmath>
  6. using namespace std;
  7. int a[5][5],path[5],cnt=0,x[10][10];
  8. void dfs(int m,int n,int inx){
  9. if (x[m+1][n]==1){
  10. x[m+1][n]=0;
  11. dfs(m+1,n,inx);
  12. }
  13. if (x[m-1][n]==1){
  14. x[m-1][n]=0;
  15. dfs(m-1,n,inx);
  16. }
  17. if (x[m][n+1]==1){
  18. x[m][n+1]=0;
  19. dfs(m,n+1,inx);
  20. }
  21. if (x[m][n-1]==1){
  22. x[m][n-1]=0;
  23. dfs(m,n-1,inx);
  24. }
  25. }
  26. bool yes(){
  27. memset(x,0,sizeof(x));
  28. for(int i=0;i<5;i++){
  29. x[(path[i]-1)/4][(path[i]-1)%4]=1;//一开始写成了path[i]%4-1,很快debug完成
  30. }
  31. int tot=0;
  32. for(int i=0;i<3;i++){
  33. for(int j=0;j<4;j++){
  34. if (x[i][j]==1) dfs(i,j,++tot);
  35. }
  36. }
  37. if (tot==1) return true;
  38. else return false;
  39. }
  40. void solve(int cur){
  41. if (cur>=5){
  42. if (yes()){
  43. cnt++;
  44. for(int i=0;i<5;i++) cout<<path[i]<<" ";
  45. cout<<endl;
  46. }
  47. return;
  48. }
  49. else{
  50. for(int i=1;i<=12;i++){
  51. bool ok=true;
  52. if (cur==0||i>path[cur-1]){
  53. for(int j=0;j<cur;j++){
  54. if (path[j]==i){
  55. ok=false;
  56. break;
  57. }
  58. }
  59. if (ok){
  60. path[cur]=i;
  61. solve(cur+1);
  62. }
  63. }
  64. }
  65. }
  66. }
  67. int main(){
  68. int temp=1;
  69. for(int i=0;i<3;i++){
  70. for(int j=0;j<4;j++){
  71. a[i][j]=temp++;
  72. }
  73. }
  74. solve(0);
  75. cout<<cnt<<endl;
  76. return 0;
  77. }

8.四平方和

这届蓝桥杯怎么这么难呢……

思路:枚举,设一个该数平方根为上线以提高运算速度。

对如何退出递归不熟练,参考了紫书上困难的串的代码才写出来

  1. /*17:02*/
  2. /*17:35 已完成 但复杂度太高 只能通过部分案例*/
  3. #include <iostream>
  4. #include <cmath>
  5. using namespace std;
  6. long long n,a[5],x;
  7. int solve(int cur,long long ctot){
  8. //printf("\ncur=%d ctot=%d\n",cur,ctot);
  9. if (cur>=4){
  10. if (ctot==n) return 0;//已经找到解
  11. else return 1;
  12. }
  13. for(long long i=0;i<=sqrt(n*1.0);i++){
  14. long long ttot=ctot+i*i;
  15. //printf("ctot=%d\n",ttot);
  16. if (ttot<=n){
  17. a[cur]=i;
  18. //printf("i=%d cur=%d ctot=%d\n",i,cur,ttot);
  19. if (!solve(cur+1,ttot)) {
  20. return 0;//已找到解
  21. }
  22. }
  23. }
  24. return 1;
  25. }
  26. int main(){
  27. cin>>n;
  28. solve(0,0);
  29. for(int i=0;i<4;i++){
  30. cout<<a[i]<<" ";}
  31. system("pause");
  32. return 0;
  33. }

运行时间还是太长了,参考网上的做法,进行数据重复利用,用一个数组存放运算过的数,代码略。

效率似乎还是不够


2019.3.10

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注