不点两面 (安全牌)
我愿称这思路为 先斩后奏【拿到牌直接先分出安全牌,先不管(op)是拿牌 还是弃牌】(有python和c++的代码 思路一样 可以看逐行注解)
c++代码
#include<bits/stdc++.h>
const int N=1e7+10;
int a[N];//判断安全牌是否使用过
using namespace std;
int safe[3];//暂存安全牌
int main(){
memset(a,0, sizeof(a));//所有安全牌数值置0
int m,q;
int cnt=0;//判断有几张安全牌
scanf("%d%d",&m,&q);
for(int i=1;i<=q;i++){
int op;// 1对方拿牌 2对方弃牌
int sum;//对方拿到的牌
scanf("%d%d",&op,&sum);
int l=(sum-3);//对方拿到的牌 你对应的安全牌(x-3)
int r=(sum+3);//对方拿到的牌 你对应的安全牌(x+3)
safe[1]=l;
safe[2]=r;
for(int j=1;j<=2;j++){
if(safe[j]<1 || safe[j]>m)continue;//越界抛出
//对方拿牌
if(op==1){
if(a[safe[j]]==0){//表示这个安全牌没使用
cnt++;//安全牌数量增加
}
//对应安全牌数量增加
a[safe[j]]++;
}
//对方弃牌
else{
if(a[safe[j]]==1){
//若对方手上只有一张并且要扔
// 那你对应的安全牌也可以扔了
cnt--;//安全牌数量减少
}
//对应安全牌数量减少
a[safe[j]]--;
}
}
printf("%d\n",cnt);
}
}
Python3 代码
m,q = map(int,input().split())
book = [0 for i in range(m+10)]
cnt = 0
for i in range(q):
op,num = map(int,input().split())
#拿到数直接判安全牌
for j in [num-3,num+3]:
if j > m or j < 1:
continue
#加入
if op == 1:
#判断该数是否使用过
if book[j] == 0:
cnt += 1
book[j] += 1
#抛出
else:
if book[j] == 1:
cnt -= 1
book[j] -= 1
print(cnt)
如有错,请大佬在评论指出,谢谢