题意:传送门
题解:从都是 0 0 0和 1 1 1组成的序列中截取一个子串,一个子序列,使得截取出来的 0 0 0和 1 1 1的个数相同,子序列就很好办,直接取序列中 0 0 0和 1 1 1个数最小的一个就可以,对于子串而言,可以考虑成这样的,将序列中的 0 0 0处理成 − 1 -1 −1,将序列中的 1 1 1处理成 1 1 1,进行前缀和,也就是说如果存在一个子串的话,那么必然这个子串相加和为 0 0 0,然后记录前缀和出现的最左边的值和最右边的值即可。
附上代码:
#include
#include
#include
using namespace std;
const int N=1e5+5;
int n,a[N],cnt0,cnt1,dp[N],minn[2*N],maxx[2*N],res;
int main()
{
scanf("%d",&n);
memset(minn,0x3f,sizeof(minn));
memset(maxx,-1,sizeof(maxx));
minn[N-3]=0;
maxx[N-3]=0;
for(int i=1,tmp;i<=n;i++){
scanf("%1d",&tmp);
if(tmp==0){
cnt0++;
a[i]=-1;
}else if(tmp==1){
cnt1++;
a[i]=1;
}
dp[i]=dp[i-1]+a[i];
tmp=dp[i]+1e5+2;
minn[tmp]=min(minn[tmp],i);
maxx[tmp]=max(maxx[tmp],i);
res=max(maxx[tmp]-minn[tmp],res);
}
printf("%d %d\n",res,2*min(cnt0,cnt1));
return 0;
}
题意:传送门
题解:给的pdf说的相当好了,直接粘过来了。
附上代码:
#include
#include
#include
using namespace std;
const int N=1e5+5;
int n,a[N],cnt0,cnt1,dp[N],minn[2*N],maxx[2*N],res;
int main()
{
scanf("%d",&n);
memset(minn,0x3f,sizeof(minn));
memset(maxx,-1,sizeof(maxx));
minn[N-3]=0;
maxx[N-3]=0;
for(int i=1,tmp;i<=n;i++){
scanf("%1d",&tmp);
if(tmp==0){
cnt0++;
a[i]=-1;
}else if(tmp==1){
cnt1++;
a[i]=1;
}
dp[i]=dp[i-1]+a[i];
tmp=dp[i]+1e5+2;
minn[tmp]=min(minn[tmp],i);
maxx[tmp]=max(maxx[tmp],i);
res=max(maxx[tmp]-minn[tmp],res);
}
printf("%d %d\n",res,2*min(cnt0,cnt1));
return 0;
}
题意:传送门
题解:画一条线将所有点分成两半,两关键字排序,先按照x排,再按照y排,直接看中间两个点,如果x不相同,就可以通过画竖线稍微偏一点来确定,如果x相同的情况下,那么就得画一条横轴偏斜的线将两个拆开,正好将这条线穿过中间两个点的y轴中间即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+10;
struct node{
int x,y;
bool operator < (const node p){
if(x==p.x) return y>p.y;
return x<p.x;
}
}a[maxn];
int main(){
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i].x,&a[i].y);
}
sort(a+1,a+n+1);
int cnt=n/2;
int x1,x2,y1,y2;
if(a[cnt].x==a[cnt+1].x){
x1=a[cnt].x-1;
x2=x1+2;
y1=-1e8;
y2=a[cnt+1].y-y1+a[cnt+1].y+1;
}else{
x1=a[cnt].x;
y1=-1e8;
x2=x1+1;
y2=1e9-1;
}
printf("%d %d %d %d\n",x1,y1,x2,y2);
}
}
题意:传送门
题解:直接使用unorder_map与list模拟即可。
#include<bits/stdc++.h>
#define ll long long
#define pli pair<ll,int>
#define iter list<pli>::iterator
using namespace std;
int T,q,m,opt,v;
char s[15];
ll trans()
{
ll ans=1;
for(int i=0;s[i];i++){
ans=ans*10+s[i]-'0';
}
return ans;
}
int main()
{
scanf("%d",&T);
while(T--){
unordered_map<ll,iter>mp;
list<pli>lis;
scanf("%d%d",&q,&m);
for(int i=0;i<q;i++){
scanf("%d%s%d",&opt,s,&v);
ll tmp=trans();
if(opt==0){
if(mp.find(tmp)==mp.end()){
printf("%d\n",v);
lis.push_back({tmp,v});
mp[tmp]=--lis.end();
}else{
v=(*mp[tmp]).second;
printf("%d\n",v);
lis.erase(mp[tmp]);
lis.push_back({tmp,v});
mp[tmp]=--lis.end();
}
if((int)lis.size()>m){
mp.erase(lis.front().first);
lis.pop_front();
}
}else{
if(mp.find(tmp)==mp.end()){
printf("Invalid\n");
}else{
iter pos=mp[tmp];
if(v==0)printf("%d\n",(*pos).second);
else if(v==1){
if(pos==--lis.end()){
printf("Invalid\n");
}else{
printf("%d\n",(*++pos).second);
}
}else{
if(pos==lis.begin()){
printf("Invalid\n");
}else{
printf("%d\n",(*--pos).second);
}
}
}
}
}
}
return 0;
}