zoukankan      html  css  js  c++  java
  • D. Playlist 思维

    D. Playlist 思维

    题目大意:

    Arkady的播放列表最初包含 (n) 首歌曲,按照它们在播放列表中出现的顺序从 1到 (n) 编号。 Arkady从歌曲1开始开始逐一收听播放列表中的歌曲。播放列表循环播放,听完最后一首歌后,Arkady将从头开始继续听。

    每首歌曲都有一个类型 (a_i),它是一个正整数。让Arkady完成听一首类型为 (y) 的歌曲,倒数第二首听过的歌曲的类型为 (x)。如果gcd(x,y)= 1,则从播放列表中删除最后收听的歌曲(类型y)。之后,他将继续正常收听,跳过已删除的歌曲并忘记他之前听过的歌曲。换句话说,删除歌曲后,他不能立即删除下一首歌曲。

    比如:最开始是的列表是 ([5,9,2,10,15])

    • 因为 (gcd(5,9)=1) 所以,删掉9,就变成 ([5,2,10,15])
    • 虽然现在 (gcd(5,2)=1) 但是不会继续删掉 2,而是会去比较 (gcd(2,10)) 因为不是等于1,所以不会删掉10
    • 继续比较 (gcd(10,15)) 也不会删掉
    • 然后比较 (gcd(15,5)) 也不会删
    • 然后比较 (gcd(5,2)) 因为等于1 ,所以删掉2
    • 最后一致循环都不会删掉任意一个值,所以最后的序列是 ([5,10,15])

    题解:

    挺思维的。

    • 首先发现进行一轮之后,下一轮需要判断的点,只有之前进行比较 (gcd(x,y)=1)(x)(y) 被删掉了)
    • 所以只要把之前的 (x) 按照顺序放入一个队列中即可。
    • 这个还有一个删的操作,这个只要把下一个位置用一个数组存下来即可。
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5+10;
    typedef long long ll;
    int to[maxn],a[maxn],vis[maxn];
    queue<int>que;
    vector<int>ans;
    void init(int n){
        ans.clear();
        while(!que.empty()) que.pop();
        for(int i=0;i<n;i++) to[i] = (i+1)%n,vis[i] = 0;
    }
    int gcd(int a,int b){
        return b==0?a:gcd(b,a%b);
    }
    void debug(int n){
        for(int i=0;i<n;i++) printf("to[%d]=%d  ",i,to[i]);
    }
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
            int n;
            scanf("%d",&n);
            init(n);
            for(int i=0;i<n;i++) scanf("%d",&a[i]);
            int id = -1;
            for(int i=0;i<=n;i++){
                if(id==-1) id = i;
                else {
                    int v = i%n,now = gcd(a[id],a[v]);
                    if(now==1) {
                        vis[v] = 1;
                        ans.push_back(v+1),que.push(id);
                        to[id] = to[v],id = -1;
                    }
                    else id = i;
                }
            }
            while(!que.empty()){
                int u = que.front();que.pop();
                if(vis[u]) continue;
                int v = to[u],now = gcd(a[u],a[v]);
    //            printf("u = %d v = %d
    ",u,v);
    //            debug(n);
                if(now==1){
                    vis[v] = 1;
                    ans.push_back(v+1),que.push(u);
                    to[u] = to[v];
                }
            }
            printf("%d",ans.size());
            for(int i=0;i<ans.size();i++){
                printf(" %d",ans[i]);
            }
            printf("
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    欧拉公式
    isap的一些想法
    错误合集
    Hello World
    PAT (Advanced Level) Practice 1068 Find More Coins
    PAT (Advanced Level) 1087 All Roads Lead to Rome
    PAT (Advanced Level) 1075 PAT Judge
    PAT (Advanced Level) 1067 Sort with Swap(0, i)
    PAT (Advanced Level) 1017 Queueing at Bank
    PAT (Advanced Level) 1025 PAT Ranking
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/14575320.html
Copyright © 2011-2022 走看看