这两题简直有异曲同工之妙,曾经很少做链表题,这次拿出来总结一下。
题目传送链接:
两题非常相似,都是用这一轮被删除的元素去更新下一轮可能被删除的元素,这样的话用双链表来实现的时间复杂度应该是接近于O(n)。但是ACWING上的这样的这一题用set会被卡,平时能用手写双链表就手写吧。
消除游戏
这一题,下一轮产生的新的边缘字符一定会在上一轮删除的字符的两边。
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
#define int long long
#define PII pair<int,int>
const int N=1e6+10;
const int INF=1e18;
int l[N],r[N],book[N],st[N];
void solve()
{
string s;
cin>>s;
int len=(int)s.size();
for(int i=1;i<s.size()-1;i++)
{
l[i]=i-1;
r[i]=i+1;
}
l[0]=-1,r[0]=1,l[len-1]=len-2,r[len-1]=-1;
vector<int>v;
for(int i=0;i<s.size();i++)v.push_back(i);
int j=1;
while(1)
{
vector<int>die;
for(int i=0;i<v.size();i++)
{
if(l[v[i]]!=-1&&r[v[i]]!=-1)
{
if(s[l[v[i]]]==s[v[i]]&&s[v[i]]!=s[r[v[i]]])
{
if(book[v[i]]!=j)die.push_back(v[i]);
if(book[r[v[i]]]!=j)die.push_back(r[v[i]]);
book[v[i]]=j,st[v[i]]=1;
book[r[v[i]]]=j,st[r[v[i]]]=1;
}
else if(s[l[v[i]]]!=s[v[i]]&&s[v[i]]==s[r[v[i]]])
{
if(book[v[i]]!=j)die.push_back(v[i]);
if(book[l[v[i]]]!=j)die.push_back(l[v[i]]);
book[v[i]]=j,st[v[i]]=1;
book[l[v[i]]]=j,st[l[v[i]]]=1;
}
}
}
if(die.size()==0)break;
v.clear();
for(int i=0;i<die.size();i++)
{
if(l[die[i]]!=-1)
{
r[l[die[i]]]=r[die[i]];
if(book[l[die[i]]]!=j)
{
v.push_back(l[die[i]]);
book[l[die[i]]]=j;
}
}
if(r[die[i]]!=-1)
{
l[r[die[i]]]=l[die[i]];
if(book[r[die[i]]]!=j)
{
v.push_back(r[die[i]]);
book[r[die[i]]]=j;
}
}
}
j++;
}
string ans="";
for(int i=0;i<s.size();i++)
if(st[i]==0)
ans+=s[i];
if(ans.size()==0)cout<<"EMPTY"<<endl;
else cout<<ans<<endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int T=1;
// cin>>T;
while(T--)solve();
return 0;
}
D. Berserk Monsters
这一题当中,假如一个位置的左右两边都没有被删除,那么下一轮左右两边的攻击和也一定不会大于自身防御,而是和上一轮一样,所以这时,依旧可以采取下一轮可能被删除的位置用这一轮被删除的位置来更新,过程用链表维护即可。
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
#define PII pair<int,int>
#define int long long
const int N=1e6+10;
const int INF=1e18;
int n;
int arr[N],brr[N],book[N],l[N],r[N];
void solve()
{
cin>>n;
for(int i=1;i<=n;i++)cin>>arr[i],book[i]=0;
for(int i=1;i<=n;i++)cin>>brr[i];
for(int i=2;i<=n-1;i++)
{
l[i]=i-1;
r[i]=i+1;
}
l[1]=-1,r[1]=2,l[n]=n-1,r[n]=-1;
vector<int>v;
for(int i=1;i<=n;i++)v.push_back(i);
for(int i=1;i<=n;i++)
{
vector<int>die;
for(int k=0;k<v.size();k++)
{
int sum=0;
if(l[v[k]]!=-1)
{
sum+=arr[l[v[k]]];
}
if(r[v[k]]!=-1)
{
sum+=arr[r[v[k]]];
}
if(sum>brr[v[k]])
{
die.push_back(v[k]);
}
}
for(int k=0;k<die.size();k++)book[die[k]]=i;
cout<<die.size()<<" ";
v.clear();
for(int k=0;k<die.size();k++)
{
if(l[die[k]]!=-1)
{
r[l[die[k]]]=r[die[k]];
if(book[l[die[k]]]!=i)
{
v.push_back(l[die[k]]);
book[l[die[k]]]=i;
}
}
if(r[die[k]]!=-1)
{
l[r[die[k]]]=l[die[k]];
if(book[r[die[k]]]!=i)
{
v.push_back(r[die[k]]);
book[r[die[k]]]=i;
}
}
}
}
cout<<endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int T=1;
cin>>T;
while(T--)solve();
return 0;
}