题链:https://leetcode-cn.com/problems/dota2-senate/
我的思路:模拟错了n发,太菜了。。。。。。。有权利投票的话,先把后面的对手ban掉,后面没有对手了的话再ban前面的对手。我用的字符串模拟的,最后看一下哪个阵营先为空即可(不知道为啥,跑的还挺快)。
实现1:
class Solution {
public:
string predictPartyVictory(string s) {
while(1){
int n=s.size();
string ss="";
int cntr=0,cntd=0,r=0,d=0;
//先ban后面的
for(int i=0;i<n;i++){
if(s[i]=='R'){
if(d) d--;
else cntr++,r++,ss+=s[i];
}else{
if(r) r--;
else cntd++,d++,ss+=s[i];
}
}
string sss="";
n=ss.size();
//再ban前面的
for(int i=0;i<n;i++){
if(ss[i]=='R'){
if(d) d--,cntr--;
else sss+=ss[i];
}else{
if(r) r--,cntd--;
else sss+=ss[i];
}
}
if(cntd==0) return "Radiant";
else if(cntr==0) return "Dire";
s=sss;
}
}
};
实现2:ban前面的时候用到了队列。
class Solution {
public:
string predictPartyVictory(string s) {
while(1){
int n=s.size();
queue<int> q1,q2;
int r=0,d=0;
for(int i=0;i<n;i++){
if(s[i]=='R'){
if(d) d--;
else{
r++;
q1.push(i);
}
}else{
if(r) r--;
else{
d++;
q2.push(i);
}
}
}
while(d&&!q1.empty())
q1.pop(),d--;
while(r&&!q2.empty())
q2.pop(),r--;
if(q2.empty()) return "Radiant";
else if(q1.empty()) return "Dire";
string ss="";
while(!q1.empty()&&!q2.empty())
if(q1.front()<q2.front()) ss+=s[q1.front()],q1.pop();
else ss+=s[q2.front()],q2.pop();
while(!q1.empty()) ss+=s[q1.front()],q1.pop();
while(!q2.empty()) ss+=s[q2.front()],q2.pop();
s=ss;
}
}
};
官方题解:两个队列,每次都抛队首,抛之前看一看哪个队首更小,因为他会留下进入下一轮,平移加个n表示下一轮就好。(太菜了,这一看就是队列,因为要ban前面的,也就是先入先出,摆明了队列。)
class Solution {
public:
string predictPartyVictory(string s) {
int n = s.size();
queue<int> q1,q2;
for(int i=0;i<n;i++)
if(s[i]=='R') q1.push(i);
else q2.push(i);
while(!q1.empty()&&!q2.empty()){
if(q1.front()<q2.front())
q1.push(q1.front()+n);
else
q2.push(q2.front()+n);
q1.pop();
q2.pop();
}
return q1.empty()?"Dire":"Radiant";
}
};