2017南宁区域赛 三题题解

秒速五厘米 2023-06-06 08:27 137阅读 0赞

知识共享许可协议
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191010211023395.png
https://nanti.jisuanke.com/t/A1537
H The Game of Life
根据题意我们可以确定在321轮中内,活细胞的所能到达的范围一定是在600*600这个范围内。那么我们可以在每一轮中考虑该细胞在下一轮中是不是会存活,并且该细胞的周围8个细胞中是否会有死细胞存活过来。这样的话,我们要保持的就是每个活细胞的位置了。就不需要遍历整张图,复杂度大大降低。同时,有一个地方需要注意,就是死细胞变活细胞时的情况。
如下例:
1 1
0 1
这个例子中,在遍历活细胞的时候,都会访问到0那个死细胞。会访问三次,所以我们需要标记一下,避免重复。

  1. #include"stdio.h"
  2. #include"string.h"
  3. #include"queue"
  4. #include"algorithm"
  5. using namespace std;
  6. typedef struct node
  7. {
  8. int x,y;
  9. int t;
  10. node() {};
  11. node(int a,int b,int c)
  12. {
  13. x = a;
  14. y = b;
  15. t = c;
  16. };
  17. } Node;
  18. const int stand = 300;
  19. const int dirx[8] = {-1,0,1,0,1,-1,-1,1};
  20. const int diry[8] = {0,-1,0,1,1,-1,1,-1};
  21. int T,n,m;
  22. int old_Graph[610][610],new_Graph[610][610];
  23. queue<Node> Q,P;
  24. int main()
  25. {
  26. scanf("%d",&T);
  27. while(T --)
  28. {
  29. while(Q.size())
  30. Q.pop();
  31. while(P.size()) P.pop();
  32. scanf("%d%d",&n,&m); getchar();
  33. for(int i = 0; i < 610; i ++)
  34. for(int j = 0; j < 610; j ++)
  35. new_Graph[i][j] = old_Graph[i][j] = 0;
  36. for(int i = 1; i <= n; i ++)
  37. {for(int j = 1; j <= m; j ++)
  38. {
  39. char x;
  40. scanf("%c",&x);
  41. new_Graph[stand + i][stand + j] = old_Graph[stand + i][stand + j] = (x == '#');
  42. if(old_Graph[stand + i][stand + j] == 1)
  43. {
  44. Q.push({stand + i,stand + j,0});
  45. }
  46. }getchar();
  47. }
  48. int maxsize = Q.size(),maxcnt = 0;
  49. for(int i = 1; i <= 321; i ++)
  50. {
  51. while(1)
  52. {
  53. if(Q.size() == 0 || Q.front().t == i)
  54. break;
  55. Node p = Q.front();
  56. Q.pop();
  57. int x = p.x,y = p.y,cnt = 0;
  58. for(int j = 0; j < 8; j ++)
  59. {
  60. int X = x + dirx[j];
  61. int Y = y + diry[j];
  62. if(old_Graph[X][Y] == 1)
  63. {
  64. cnt ++;
  65. }
  66. }
  67. if(cnt == 2 || cnt == 3)
  68. {
  69. Q.push({x,y,p.t + 1});
  70. }
  71. else
  72. {
  73. new_Graph[x][y] = 0;
  74. P.push({x,y,0});
  75. }
  76. for(int j = 0; j < 8; j ++)
  77. {
  78. int X = x + dirx[j];
  79. int Y = y + diry[j];
  80. if(old_Graph[X][Y] == 0 && new_Graph[X][Y] == 0)
  81. {
  82. int cnt = 0;
  83. for(int j = 0; j < 8; j ++)
  84. {
  85. int X1 = X + dirx[j];
  86. int Y1 = Y + diry[j];
  87. if(old_Graph[X1][Y1] == 1)
  88. {
  89. cnt ++;
  90. }
  91. }
  92. if(cnt == 3)
  93. {
  94. new_Graph[X][Y] = 1;
  95. Q.push({X,Y,p.t + 1});
  96. P.push({X,Y,1});
  97. }
  98. }
  99. }
  100. }
  101. while(P.size())
  102. {
  103. Node p = P.front(); P.pop();
  104. old_Graph[p.x][p.y] = p.t;
  105. }
  106. if(maxsize < Q.size())
  107. {
  108. maxsize = Q.size();
  109. maxcnt = i;
  110. }
  111. }
  112. printf("%d %d %d\n",maxcnt,maxsize,Q.size());
  113. }
  114. }

https://nanti.jisuanke.com/t/A1538
I - Rake It In
看到数据范围,很容易想到dfs。直接考虑dfs即可

  1. #include"stdio.h"
  2. #include"string.h"
  3. #include"algorithm"
  4. using namespace std;
  5. int T,k;
  6. int Graph[5][5];
  7. int sum(int i,int j)
  8. {
  9. return Graph[i][j] + Graph[i][j + 1] + Graph[i + 1][j] + Graph[i + 1][j + 1];
  10. }
  11. int tran_2(int i,int j)
  12. {
  13. int x1 = Graph[i][j];
  14. int x2 = Graph[i][j + 1];
  15. int x3 = Graph[i + 1][j];
  16. int x4 = Graph[i + 1][j + 1];
  17. Graph[i][j] = x3;
  18. Graph[i][j + 1] = x1;
  19. Graph[i + 1][j + 1] = x2;
  20. Graph[i + 1][j] = x4;
  21. }
  22. int tran_1(int i,int j)
  23. {
  24. int x1 = Graph[i][j];
  25. int x2 = Graph[i][j + 1];
  26. int x3 = Graph[i + 1][j];
  27. int x4 = Graph[i + 1][j + 1];
  28. Graph[i][j] = x2;
  29. Graph[i][j + 1] = x4;
  30. Graph[i + 1][j + 1] = x3;
  31. Graph[i + 1][j] = x1;
  32. }
  33. int dfs(int p)
  34. {
  35. if(p == 2 * k)
  36. {
  37. int minx = 9999;
  38. for(int i = 1; i <= 3; i ++)
  39. for(int j = 1; j <= 3; j ++)
  40. minx = min(minx,sum(i,j));
  41. return minx;
  42. }
  43. if(p % 2 == 1)
  44. {
  45. int maxx = 0;
  46. for(int i = 1; i <= 3; i ++)
  47. for(int j = 1; j <= 3; j ++)
  48. {
  49. tran_1(i,j);
  50. maxx = max(maxx,sum(i,j) + dfs(p + 1));
  51. tran_2(i,j);
  52. }
  53. return maxx;
  54. }
  55. int minx = 9999;
  56. for(int i = 1; i <= 3; i ++)
  57. for(int j = 1; j <= 3; j ++)
  58. {
  59. tran_1(i,j);
  60. minx = min(minx,sum(i,j) + dfs(p + 1));
  61. tran_2(i,j);
  62. }
  63. return minx;
  64. }
  65. int main()
  66. {
  67. scanf("%d",&T);
  68. while(T --)
  69. {
  70. scanf("%d",&k);
  71. for(int i = 1; i <= 4; i ++)
  72. for(int j = 1; j <= 4; j ++)
  73. scanf("%d",&Graph[i][j]);
  74. printf("%d\n",dfs(1));
  75. }
  76. }

https://nanti.jisuanke.com/t/A1541L
Twice Equation
这种题,第一反应打表找规律。
发现 3 20 119
可通过oeis表也没搜到。所以一般只能线性系数不断改变来找到递推式。
可发现 f[n] = f[n -1] * 6 - f[n - 2] + 2;
数据范围大数无疑。java大数果然比C好写多了。

  1. import java.math.*;
  2. import java.io.*;
  3. import java.util.*;
  4. public class Main{
  5. public static void main(String args[]){
  6. Scanner cin = new Scanner(System.in);
  7. BigInteger[] f = new BigInteger [1500] ;
  8. BigInteger six = new BigInteger("6");
  9. BigInteger two = new BigInteger("2");
  10. f[0] = new BigInteger("3"); f[1] = new BigInteger("20");
  11. for(int i = 2; i < 1500; i ++)
  12. f[i] = f[i - 1].multiply(six).subtract(f[i - 2]).add(two);
  13. int T=cin.nextInt();
  14. while(T != 0){
  15. T --;
  16. BigInteger x = cin.nextBigInteger();
  17. for(int i = 0; i < 1500; i ++)
  18. if(x.compareTo(f[i]) <= 0)
  19. {
  20. System.out.println(f[i]); break;
  21. }
  22. }
  23. }
  24. }

发表评论

表情:
评论列表 (有 0 条评论,137人围观)

还没有评论,来说两句吧...

相关阅读