• Codeforces Round #789 (Div. 1) B. Tokitsukaze and Meeting


    翻译:

    德木风正在安排会面。会议厅里有𝑛排和𝑚列的座位。

    有𝑛⋅𝑚的学生参加了会议,其中有几个调皮的学生,也有几个认真的学生。学生被从1到𝑛⋅𝑚打分。学生们将依次进入会场。当𝑖-th学生进入会场时,他将坐在第1排的第1列,已经就座的学生将向后移动一个座位。具体来说,位于𝑖-th行𝑗-th(1≤𝑗≤𝑚−1)列的学生将移动到𝑖-th行的(𝑗+1)列,位于𝑖-th行的𝑚-th列的学生将移动到(𝑖+1)行第1-st列。

    例如,有一个2排2列的会议厅,如下图所示:


    将有4名学生依次进入会场,用二进制字符串“1100”表示,其中“0”代表淘气的学生,“1”代表严肃的学生。会议大厅的座位变化如下:


    表示一行或一列,当且仅当该行或一列中至少有一个认真的学生时为好。请在𝑖-th学生进入会场后预测好行和列的数量,为所有𝑖。

    输入
    第一个包含一个正整数𝑡(1≤𝑡≤10000)——测试用例的数量。

    对于每个测试用例,第一行包含两个整数𝑛,𝑚(1≤𝑛,𝑚≤106;1≤𝑛⋅𝑚≤106),表示会场座位有𝑛排、𝑚列。

    第二行是长度为𝑛⋅𝑚的二进制字符串𝑠,仅由0和1组成。如果𝑠𝑖等于“0”表示𝑖-th学生是一个顽皮的学生,𝑠𝑖等于“1”表示𝑖-th学生是一个严肃的学生。

    保证所有测试用例𝑛⋅𝑚的总和不超过106。

    输出
    对于每个测试用例,打印带有𝑛⋅𝑚整数的一行—在𝑖-th学生进入会议厅之后的好行和列的数量。

    例子
    inputCopy
    3.
    2 - 2
    1100
    4个2
    11001101
    2 4
    11001101
    outputCopy
    2 3 4 3
    2 3 4 3 5 4 6 5
    2 3 3 3 4 4 4 5
    请注意
    第一个测试用例显示在语句中。

    第1排学生进入会议厅后,有2个好的排和列:第1排和第1列。

    第二个学生进入会议厅后,有3个好的行和列:第1行,第1列和第2列。

    第三个同学进入会场后,4排4列都好了。

    第4个学生进入会场后,有3行3列:第2行,第1列和第2列。

    思路:

            这个是每次记录带有1的行和列,每次进一个人,都会将之前的人向后压缩。这道题刚开始看起来根本毫无头绪,不过数据范围这么大,不可能每次去单独求,所以应该是奇妙的数学规律思维题。我们考虑每次进来m个人,前边的人都要去之前那一列,所以我们可以根据这个性质来着手去解决。

            行的关系比较好找,一行中,只要有一个1,那么这一行就可以算作有1的,然后往后推,比如m=2,我们第三个人进去的时候是第一个人是去了新的一行,前m个人可以单独处理,因为每次去新的一行的只有那几个人,当有两行是,我们就可以加上之前的那一行,三个人,新的一行就是第一个人,所以我们加上h[1],之后第二行有两个人,我们就加上h[2],然后再不断处理本行的,我们就可以推出行的结论。

            接下来是列,当有了不止一行,列你会发现,它是一直对应着的,比如m=3的时候,我们有4个人,那么我们第四个人的列就对应了第一个人,直接进来第五个人,第六个人,因为都是向后推移,所以一直对应,因此我们只需要简单的加个标记,然后加和就可以得到答案。

    代码:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. using namespace::std;
    15. typedef long long ll;
    16. int n,t;
    17. inline __int128 read(){
    18. __int128 x = 0, f = 1;
    19. char ch = getchar();
    20. while(ch < '0' || ch > '9'){
    21. if(ch == '-')
    22. f = -1;
    23. ch = getchar();
    24. }
    25. while(ch >= '0' && ch <= '9'){
    26. x = x * 10 + ch - '0';
    27. ch = getchar();
    28. }
    29. return x * f;
    30. }
    31. inline void print(__int128 x){
    32. if(x < 0){
    33. putchar('-');
    34. x = -x;
    35. }
    36. if(x > 9)
    37. print(x / 10);
    38. putchar(x % 10 + '0');
    39. }
    40. int m;
    41. string s;
    42. bool l[1000005];
    43. int h[1000005];
    44. int sum[1000005];
    45. void solv(){
    46. cin>>n>>m>>s;
    47. s='@'+s;
    48. for (int i =1; i<=n*m; i++) {
    49. sum[i]=sum[i-1]+(s[i]=='1');
    50. }
    51. for (int i =1; i<=n*m; i++) {
    52. if (i>=m) {
    53. h[i]+=h[i-m];
    54. }
    55. h[i]+=(sum[i]-sum[max(i-m, 0)])>0;
    56. }
    57. int ff=1;
    58. int an=0;
    59. for (int i =1; i<=n*m; i++) {
    60. if (l[ff]==0&&s[i]=='1') {
    61. an++;
    62. l[ff]=1;
    63. }
    64. ff++;
    65. printf("%d ",an+h[i]);
    66. if (ff==m+1) {
    67. ff=1;
    68. }
    69. }printf("\n");
    70. for (int i =0; i<=n*m; i++) {
    71. sum[i]=0;h[i]=0;
    72. l[i]=0;
    73. }
    74. }
    75. int main(){
    76. ios::sync_with_stdio(false);
    77. cin.tie(); cout.tie();
    78. cin>>t;
    79. while (t--) {
    80. solv();
    81. }
    82. return 0;
    83. }
    84.  

  • 相关阅读:
    基于51单片机智能手机锂电池充电器设计
    【FreeRTOS】任务通知的使用
    【奇想星球】重磅!我们的AIGC共创社区平台上线了!
    java key锁 实现对某个key(字符串)加同步锁 带详细注释
    第15届蓝桥杯题解
    编程示例:蔡勒公式计算某一天是星期几 公式来源于1886年
    SpringIOC之Lifecycle 接口
    数字政府一网统管体系下的运维管理软件应用探讨
    Pytest单元测试框架 —— Pytest+Allure+Jenkins的应用
    GeoServe Web 管理界面 远程访问
  • 原文地址:https://blog.csdn.net/weixin_63555280/article/details/128194918