其他分享
首页 > 其他分享> > CodeForces 1484D Playlist 思维暴力

CodeForces 1484D Playlist 思维暴力

作者:互联网

题目链接

https://codeforces.com/problemset/problem/1484/D

题意

给出一个数组,从1开始循环检查,如果gcd(a[i],a[i+1])=1(若i=n,那么比较a[n]和a[1]),那么就把a[i+1]移除。注意不能连续移除两个元素。问最终移除元素的数量和移除次序

思路

被前面题难度吓到了,这边直接带点思路打暴力就可以了。

看cf评论区说什么list和循环队列啥的,也没看明白,等出官方题解再说吧。

容易想到以下性质,在我们循环检查数组时,我们没有必要每次都对数组整个检查一遍,在处理完一遍后,能够产生新答案的位置只有上一次检查过程中产生了删除元素的位置。

我们用li数组记录每一个元素右边指向的元素,对于第i个元素,初始为i+1,之后可能会不断变化,比如我们把i右边的移除,那么li[i]则变成了li[li[i]],这样处理是非常节约时间的。

我们创建数组v,初始时存放1-n的全部下标,创建临时的t数组存放可能产生新答案的位置。对于满足条件的位置i,我们把i加入数组t,把li[i]打标记防止重复访问,更新li[i],更新答案。之后让v=t,循环直到v为空为止

教训/收获

  1. 别被吓到,想到就写,很多题没那么难,别摆烂
  2. c++11里可以用emplace_back()代替push_back(),他的插入效率更高,减少了不必要的构造,拷贝,析构等。但说实话vector平时都是基本类型居多,最多用个string,效率能高多少打个问号。

代码

#include<cstdio>
#include<iostream>
#include<iomanip>
#include<map>
#include<unordered_map>
#include<string>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib> 
#include<chrono>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl "\n"
//#define int long long
//#define double long double
using namespace std;
	typedef long long ll;
	const int maxn=200505;
	const int inf=0x3f3f3f3f;
	int n,m,k;
    int a[maxn];
    int li[maxn];
    bool vis[maxn];
    vector<int>v,ans,t;

    struct custom_hash {static uint64_t splitmix64(uint64_t x) {x += 0x9e3779b97f4a7c15;x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;x = (x ^ (x >> 27)) * 0x94d049bb133111eb;return x ^ (x >> 31);}size_t operator()(uint64_t x) const {static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();return splitmix64(x + FIXED_RANDOM);}};
	signed main(){
		IOS
		#ifndef ONLINE_JUDGE
		    freopen("IO\\in.txt","r",stdin);
		    freopen("IO\\out.txt","w",stdout);
        #endif
		int tn;
		cin>>tn;
		while(tn--){
			cin>>n;
            ans.clear();v.clear();

            for(int i=1;i<=n;i++){
                cin>>a[i];
                v.emplace_back(i);
                li[i]=i+1;
                vis[i]=0;
            }
            li[n]=1;
            while(v.size()){
                t.clear();
                for(auto i:v){
                    if(vis[i])  continue;
                    if(__gcd(a[i],a[li[i]])==1){
                        ans.emplace_back(li[i]);
                        vis[li[i]]=1;
                        li[i]=li[li[i]];
                        t.emplace_back(i);
                    }
                }
                v=t;
            }
            cout<<ans.size();
            for(auto i:ans) cout<<' '<<i;
            cout<<endl;
		}
	} 
						

标签:back,Playlist,int,CodeForces,long,li,移除,1484D,include
来源: https://blog.csdn.net/TheSunspot/article/details/115147783