题目传送
题意:
给你,n块木板,再q次询问的情况下(询问时会添加或者减少木板),问在当前询问下是否能使用现有的木板构成一个正方形和一个矩形(也可以是正方形)?构成的时候,每一条边是只能用一块木板
思路:
千万不要读错了,每一条边的构成只能用一块木板的
那么我们现在只用记录现在有多少组木板长度一样的(4个为一组记为ans1),在除去前面的一组的情况下,还有多少组长度为一样的(2个为一组,记为ans2)
如果ans1 >= 2 (能构成俩个正方形) 或者 ans1 == 1 && ans2 >= 2(构成一个正方形,和一个矩形)
AC代码
#include <bits/stdc++.h>
inline int read(){char c = getchar();int x = 0,s = 1;
while(c < '0' || c > '9') {if(c == '-') s = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x*10 + c -'0';c = getchar();}
return x*s;}
using namespace std;
#define NewNode (TreeNode *)malloc(sizeof(TreeNode))
#define Mem(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x)&(-x)
const int N = 1e5 + 5;
const long long INFINF = 0x7f7f7f7f7f7f7f;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-7;
const int mod = 1e9 + 7;
const double II = acos(-1);
const double PP = (II*1.0)/(180.00);
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> piil;
int vis[N];
signed main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
int n,ans1 = 0,ans2 = 0,q,num;
cin >> n;
for(int i = 0;i < n;i++)
{
cin >> num;
if(vis[num] % 4 + 1 == 4) ans1++,ans2--;//即将构成一个4个为一组的,当然现在的2个为一组的要变成4个一组的,所以ans2--,以下同理
else if(vis[num] % 4 + 1 == 2) ans2++;
vis[num]++;
}
cin >> q;
while(q--)
{
char c;
cin >> c >> num;
if(c == '+')
{
if(vis[num] % 4 + 1 == 4) ans1++,ans2--;
else if(vis[num] % 4 + 1 == 2) ans2++;
vis[num]++;
}
else
{
if(vis[num] % 4 == 0) ans1--,ans2++;
else if(vis[num] % 4 == 2) ans2--;
vis[num]--;
}
ans1 >= 2 || (ans1 == 1 && ans2 >= 2) ? cout << "YES" << endl : cout << "NO" << endl;
}
}