题目大意:
给出一个数组,找每个位置的与序列里的其他值的差的绝对值最大值与最小值。
解题思路:
记录位置并排序,最大值肯定与排序后的头元素或尾元素的差,最小值肯定是排序后的位置的前一个元素或者后一个元素。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=200000+1000;
struct node
{
int x;
int cur;
}a[maxn];
int b[maxn];
int c[maxn];
bool cmp(node u,node v)
{
return u.x<v.x;
}
int bbs(int x)
{
if(x<0)
return -x;
return x;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
{
scanf("%d",&a[i].x);
a[i].cur=i;
}
sort(a,a+n,cmp);
for(int i=0;i<n;i++)
{
if(i==0)
b[a[i].cur]=a[i+1].x-a[i].x;
else if(i==n-1)
b[a[i].cur]=a[n-1].x-a[i-1].x;
else
b[a[i].cur]=min(bbs(a[i-1].x-a[i].x),bbs(a[i+1].x-a[i].x));
c[a[i].cur]=max(bbs(a[0].x-a[i].x),bbs(a[n-1].x-a[i].x));
}
for(int i=0;i<n;i++)
printf("%d %d\n",b[i],c[i]);
}
return 0;
}
题目大意:
给出进出日志,求房间的最小容量。
解题思路:
房间的容量取决于房间最多人的时候。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <algorithm>
using namespace std;
const int maxn=1000000+100;
int a[maxn];
int c[maxn];
int main()
{
char s[15];
int n;
while(~scanf("%d",&n))
{
memset(a,0,sizeof(a));
int d;
int ans=0,cur=0;
int sign=0;
for(int i=0;i<n;i++)
{
scanf("%s%d",s,&d);
if(s[0]=='+')
{
sign++;
a[d]=1;
c[i]=sign;
}
else
{
if(a[d]==1)
{
sign--;
a[d]=0;
c[i]=sign;
}
else
{
c[i]=c[i-1]+1;
for(int j=i-1;j>=0;j--)
c[j]++;
}
}
}
for(int i=0;i<n;i++)
{
ans=max(ans,c[i]);
}
cout<<ans<<endl;
}
return 0;
}
题目大意:
给出一段序列,求序列里的3个数成等比数列,且比值为k的数量。
解题思路:
配句中间那个元素,前面那个元素和后面那个元素出现的次数相乘就可。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <algorithm>
using namespace std;
map<long long,int> ma;
map<long long,int> ma2;
long long a[210000];
int main()
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=0; i<n; i++)
{
cin>>a[i];
}
ma.clear(),ma2.clear();
for(int i=n-1; i>=0; i--)
{
ma[a[i]]++;
}
long long ans=0;
for(int i=0; i<n; i++)
{
ma[a[i]]--;
long long cur=0;
if(ma[a[i]*k])
{
cur=ma[a[i]*k];
if(a[i]%k==0)
{
if(ma2[a[i]/k])
{
cur=cur*ma2[a[i]/k];
//cout<<cur<<" "<<ma2[a[i]/k]<<" "<<a[i]/k<<endl;
}
else
cur=0;
}
else
cur=0;
}
ma2[a[i]]++;
ans+=cur;
//cout<<cur<<endl;
}
cout<<ans<<endl;
return 0;
}
题目大意:
n个1*1的小格子,k个1*a的小船,要将k个小船放进n个格子内,不能相邻,接着m个操作,每次让第xi个格子不能用,求第几个操作后船就放不下了。
解题思路:
每次操作,只会讲1段区间分成2段,只需求分开前后少放了几个小船。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
using namespace std;
set<int> s;
int main()
{
int n,k,a;
scanf("%d%d%d",&n,&k,&a);
int m,x;
scanf("%d",&m);
s.insert(0);
s.insert(n+1);
int ans=-1;
int cur=1+(n-a)/(a+1),x1,x2;
//cout<<cur<<endl;
if(cur<k)
{
ans=0;
}
for(int i=0;i<m;i++)
{
scanf("%d",&x);
if(ans!=-1)
continue;
int temp=*(--s.upper_bound(x));
int tempd=*(s.upper_bound(x));
s.insert(x);
//cout<<temp<<" "<<tempd<<endl;
x1=0,x2=0;
if(tempd-temp-1>=a)
x1=1+(tempd-temp-1-a)/(a+1);
if(x-temp-1>=a)
x2=1+(x-temp-1-a)/(a+1);
if(tempd-x-1>=a)
x2+=(1+(tempd-x-1-a)/(a+1));
//cout<<x1<<" "<<x2<<endl;
cur-=(x1-x2);
if(cur<k)
{
ans=i+1;
}
}
cout<<ans<<endl;
return 0;
}