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;
    }
    
  • 相关阅读:
    Linux下文件属性(drwxr-xr-x)详解以及(-rwxrwxrwx=777)(转)
    Linux中chown和chmod的区别和用法(转)
    以root用户身份在jenkins中运行shell命令
    Java中Properties配置文件读取
    Java分布式服务框架Dubbo初探(待实践)
    Servlet3.0新特性
    Java中System.getProperty()的参数
    Java获取路径的方法分析详解(Application/Web)
    Java中的JAR/EAR/WAR包的文件夹结构说明(转)
    JAR包中的MANIFEST.MF文件详解以及编写规范
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/14575320.html
Copyright © 2011-2022 走看看