ht的生日party

题目链接:传送门

题解,思路写在代码里面。

递归:

#include <iostream>
#include <cstring>
#include <cstdio>
 
using namespace std;
int n, m;
  
// 假设一个序列 一共 7人 A:  1, 2, 3, 4, 5, 6 ,7
// m = 3
 
// 第一次出列 队列只剩下5人:
// 1, 2, 4, 5, 7
// 因为第二次要从尾部开始数:
// 队列应为 B:  7, 5, 4, 2, 1
 
// BchangeintoA() 函数是将求得 "数组B中下标为 i的人" 在 "数组 A中的下标"
// 下标 从 1 开始 
// 例如 7, 在B中的下标为 1, 在A中下标为 7
// 例如 2, ............. 4, ........... 2 
// alen 数组A 的长度 
int BchangeintoA(int alen, int i, int blen) { 
    i = blen+1 - i;
    int temp = i + (i-1)/(m-1);
    return temp;
}
 
const int N = 1000100;
int F[N]; // F[N] 不为-1 则表示如果队列为N,唱歌的人的编号
// Example: F[2] = 1 , 如果序列长度为2,编号为1的 人唱歌
// 所有人下标从1开始
 
int Work(int num) {
    // 函数f 是去求解f[num],即队列中的人数 为num时唱歌的人的编号
    if(F[num] != -1) {
        return F[num]; 
    }
     
    if(num < m){
        F[num] = 1;
        return 1;
    }
 
    Work(num-num/m);
    // 减而治之,例如如果是 7 个人的队列,在数一遍之后只剩下五个人
 
    F[num] = BchangeintoA(num, F[num-num/m], num-num/m);
    // num >= m :  每一个F[num] 都是有 F[num-num/m] 推过来 
     
//    for(int i=1; i<=num; i++) {
//      cout << F[i] << " "; 
//  } 
//  cout << endl;
     
    return F[num];
}
 
int main(){
    int T;
    cin >> T;
    for(int t=1; t<=T; t++) {
        cin >> n >> m;
 
        memset(F, -1, sizeof(F)); // 对 f 进行初始化
         
        int x;
        for(int i=1; i<=n; i++) {
            scanf("%d",&x);
            printf("%d\n",Work(x));
        }
    }
    return 0;
}

递推:

#include <iostream>
#include <cstring>
#include <cstdio> 
using namespace std;
 
const int N = 1000100;
int F[N];
int n, m;
  
int BchangeintoA(int alen, int i, int blen) { 
    i = blen+1 - i;
    int temp = i + (i-1)/(m-1);
    return temp;
}
 
int main(){
    int T;
    cin >> T;
    for(int t=1; t<=T; t++) {
        cin >> n >> m;
 
        memset(F, -1, sizeof(F)); // 对 f 进行初始化
        for(int i=1; i<m; i++) {
            F[i] = 1;
        }
         
        int x;
        int max = m-1;
         
        for(int i=1; i<=n; i++) {
            scanf("%d",&x);
            if(x <= max) {
                printf("%d\n",F[x]);
            }
            else {
                for(int i=max+1; i<=x; i++) {
                    F[i] = BchangeintoA(i, F[i-i/m], i-i/m);
                }
                max = x;
                printf("%d\n",F[max]);
            }
//          for(int i=1; i<=max; i++){
//              printf("%d ",F[i]);
//          }
//          printf("\n");
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38737992/article/details/80056032
ht
HT5
今日推荐