链接:https://codeforces.com/contest/1484/problem/D
题意:
给你一个数组,每次找到一对互质的数时,删去其中第二个,不能连续删除,求最终删除的顺序。
思路:
按照题目模拟就好了,需要用数据结构优化。
每次取出队首的数,判断是否和它的下一位互质,如果是的话将下一位删去,用数组模拟链表,就只需要将nex[x]指向nex[nex[x]],再将队首的数放回队尾。直到队列为空。
这个题一开始我只用了双端队列来写,按上述思路模拟,也是对的,不过最后一个点会超时。就很神奇,加了一个链表就过了,感觉好像是差不多的思路。
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
#define PII pair<int,int>
deque<int> q;
vector<int> ans;
int nex[maxn],a[maxn],vis[maxn];
int gcd(int a,int b){
return b == 0 ? a:gcd(b,a % b);
}
int main()
{
ios::sync_with_stdio(false);
int t,n,j,cnt,pos;
PII x1,x2;
cin>>t;
while(t--){
cnt = 0;
q.clear();
ans.clear();
cin>>n;
for(int i = 1;i <= n; i++){
cin>>j;
a[i] = j;
nex[i - 1] = i;
q.push_back(i);
vis[i] = 0;
}
nex[n] = 1;
while(!q.empty()){
int x = q.front();q.pop_front();
// cout<<x<<endl;
if(vis[x])
continue;
if(gcd(a[x],a[nex[x]]) == 1){
ans.push_back(nex[x]);
vis[nex[x]] = 1;
nex[x] = nex[nex[x]];
q.push_back(x);
}
}
cout<<ans.size()<<" ";
for(auto i : ans)
cout<<i <<" ";
cout<<endl;
}
return 0;
}
会 T的纯队列做法:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
#define PII pair<int,int>
deque<PII > q;
vector<int> ans;
PII pos[maxn];
int gcd(int a,int b){
return b == 0 ? a:gcd(b,a % b);
}
int main()
{
int t,n,a,cnt;
PII x1,x2;
cin>>t;
while(t--){
cnt = 0;
q.clear();
ans.clear();
cin>>n;
for(int i = 1;i <= n; i++){
cin>>a;
q.push_back({
a,i});
}
while(!q.empty()){
x1 = q.front();
q.pop_front();
q.push_back(x1);
x2 = q.front();
// cout<<x1.first<<" "<<x2.first<<endl;
if(gcd(x1.first,x2.first) != 1)
cnt++;
else{
cnt = 0;
ans.push_back(x2.second);
q.pop_front();
}
if(cnt > q.size() || q.size() == 0)
break;
}
cout<<ans.size()<<" ";
for(auto i : ans)
cout<<i <<" ";
cout<<endl;
}
return 0;
}