这次的题比上次的略难了点。。索性的是没有被人HACK。。
第一题去数字,去最后一位或者倒数第二位,很简单,比较一下就行了。。
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <string>
using namespace std;
int main()
{
string tar;
int res;
cin>>tar;
res=atoi(tar.c_str());
if(res>=0)
cout<<res<<endl;
else if(res<0 && res>=-9)
cout<<0<<endl;
else
{
int ta,tb;
string tas,tbs;
for(int i=0;i<=tar.length()-2;i++)
{
tas+=tar[i];
}
ta=atoi(tas.c_str());
for(int j=0;j<=tar.length()-3;j++)
{
tbs+=tar[j];
}
tbs+=tar[tar.length()-1];
tb=atoi(tbs.c_str());
if(ta>tb)
{
cout<<ta<<endl;
}
else
{
cout<<tb<<endl;
}
}
return 0;
}
第二题直接做会超时,和某人讨论了一下,决定采用数据结构——树状数组。62MS AC,然后看别人代码,发现是杀鸡用牛刀了。L,R检测到不同直接加数组标记,然后R-L看看值就可以了,也不是很慢。
/*
题意:
给你一个数列,然后有m次查询,每次查询一段区间 [l,r] 内不大于 h 的值的个数。
解法:
离线 树状数组
1、若 a[i].h > q[j].h,则从 i 以后的 a[i].h 也不会再对这个查询的解有影响。此时我们可以得到这个查询的解 getsum(r) - getsum(l-1) 。
2、若 a[i].h <= q[j].h,则它会且仅会对从 j 以后的每个 q[j].h 产生影响。于是我们需要在区间中对这个位置加1,然后让 i 向后移动。
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int N=100009;
const int maxn=1000009;
int d[N],ans[N],n;
struct node
{
int l,r,id;
}q[N],p[N];
int lowbit(int x)
{
return x&(-x);
}
int cmp(node a,node b)
{
return a.r<b.r;
}
void add(int x,int data)
{
for(;x<=n;x+=lowbit(x))d[x]+=data;
//注意这里的n不一定是数据量。可能是数据中最大的一个
}
int getsum(int x)
{
int ret=0;
for(;x;x-=lowbit(x))ret+=d[x];
return ret;
}
char s[maxn];
int a[maxn],l,r;
int main()
{
s[0]='*';
a[1]=0;
int i,j,m;
while(scanf("%s",(s+1))!=EOF)
{
memset(d,0,sizeof(d));
n=strlen(s+1);
for(i=2;i<=n;i++)
{
if(s[i]==s[i-1])a[i]=a[i-1]+1;
else a[i]=0;
if(a[i])add(i,1);
}
cin>>m;
for(j=0;j<m;j++)
{
scanf("%d%d",&l,&r);
printf("%d\n",getsum(r) - getsum(l));
}
}
return 0;
}
你问我三四五?。。。不会啊。。。