还是补昨天的博客,昨天卡在一道题上快卡疯了,算法很简单,但是细节巨多,超级多,真是考验我基本功。我这次还是先整理下最近做的比赛题目并整理下hiho上的重点题目。
牛客练习赛13
1,幸运数字1
水题,找4和7谁出现的次数多。
2,幸运数字2
定义一个数字为幸运数字当且仅当它的所有数位都是4或者7。
比如说,47、744、4都是幸运数字而5、17、467都不是。
定义next(x)为大于等于x的第一个幸运数字。给定l,r,请求出next(l) + next(l + 1) + ... + next(r - 1) + next(r)。
因为数据量只有1e9,所以只包含4和7的数字只有500多个,所以先用深搜打表,排序,然后暴力一遍l到r
vector<ll>q;
void dfs(ll x,int cnt)
{
if(cnt==10) return ;
ll ans;
ans=x*10+4;
q.push_back(ans);
dfs(ans,cnt+1);
ans=x*10+7;
q.push_back(ans);
dfs(ans,cnt+1);
}
int main()
{
q.clear();
q.push_back(4);
q.push_back(7);
dfs(4,1);
dfs(7,1);
sort(q.begin(),q.end());
ll l,r;
scanf("%lld%lld",&l,&r);
ll ans=0;
for(int i=0;i<q.size();i++)
{
if(q[i]>=l&&q[i]<=r)
{
ans=ans+q[i]*(q[i]-l+1);
l=q[i]+1;
continue;
}
if(q[i]>r)
{
ans=ans+q[i]*(r-l+1);//这里是个细节,因为l<=r,所以还有一个大于r的数要处理
break;
}
}
cout<<ans<<endl;
}
3,幸运数字3
定义一个数字为幸运数字当且仅当它的所有数位都是4或者7。比如说,47、744、4都是幸运数字而5、17、467都不是。假设现在有一个数字d,现在想在d上重复k次操作。假设d有n位,用d1,d2,...,dn表示。对于每次操作,我们想要找到最小的x (x < n),使得dx=4并且dx+1=7。如果x为奇数,那么我们把dx和dx+1都变成4;否则,如果x为偶数,我们把dx和dx+1都变成7;如果不存在x,那么我们不做任何修改。现在请问k次操作以后,d会变成什么样子。
这个有规律的,先找到47出现,判断4是偶数上还是奇数,只有当偶数时才会对前面的数产生影响,此时前面如果是4,一定是奇数位上,此时只对后面有影响,继续向后就可以了。
char str[100005];
int main()
{
ll n,k;
scanf("%lld%lld",&n,&k);
scanf("%s",str);
for(int i=0;i<n;i++)
{
if(k==0) break;
if(str[i]=='4'&&str[i+1]=='7')
{
if((i+1)%2==1)
{
if(k>=1)
{
str[i]='4';
str[i+1]='4';
k--;
}
else break;
}
else
{
if(k>=1)
{
str[i]='7';
k--;
}
else break;
if(i==0) continue;
if(str[i-1]=='4')
{
if(k%2==1) str[i]='4';
else str[i]='7';
break;
}
else {continue;}
}
}
}
cout<<str<<endl;
}
牛客小白月赛1
I题:あなたの蛙が帰っています
毕竟G题还没完全弄懂。其他都很水。
I题之前一直没把题目读懂,读懂后简直后悔死了,就是裸的卡特兰数。之前没特别关注过卡特兰数对单调栈的应用,果然吃亏了。
http://blog.sina.com.cn/s/blog_6aefe4250101asv5.html
hihocoder 1604 股票价格2
题目:小Hi最近在关注股票,为了计算股票可能的盈利,他获取了一只股票最近N天的价格A1~AN。
在小Hi的策略中,每天可以在下列三种操作中选取一种:
1.什么也不做;
2.按照当天的价格买进一个单位的股票;
3.按照当天的价格卖出部分或所有股票。
现在小Hi希望能够知道,如果在N天前手中持有的股票数为0,并且假设拥有无限的金钱,在这N天结束能够获得的最大利润是多少?
这个题刚开始我是想用线段树做的,用线段树处理出来区间最大值,然后从左到右依次处理一直到最后,最差的情况也就是单调递减的序列,也就是nlog(n)。可后来转换思路,发现如果从后向前处理,不断更新最大值进行加和,代码更简单,只要n就可以。这道题其实这个转换思路比较印象深刻。
int a[1000005];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
int ans=0;
int maxn=a[n];
for(int i=(n-1);i>=1;i--)
{
if(a[i]<=maxn) ans+=(maxn-a[i]);
else
{
maxn=a[i];
}
}
cout<<ans<<endl;
}
有点晚了,先整理这些,晚安