昨天晚上睡不着,起床,开了一套cf,
题目链接:https://codeforces.com/contest/1005
5题滚粗。都是些简单题。。只是记录下刷题记录
E题可能有点难想。。。
A. Tanya and Stairways
题意:上楼梯,每上一楼梯则喊出一个数,例如:12341234 当重新从1开始喊时代表开始新的台阶。
问走过台阶的个数和输出高度
找到一个递减计入答案即可
B. Delete from the Left
两个字符,每次只能删两个字符种其中一个 的最左边的字符,问最少多少次操作,使得两个字符相同
求出后缀相同的字符长度即可,总长减去这个长度就是答案。
C. Summarize to the Power of Two
题意:n个数字,问最少删除多少个数,使得,每个数都能找到另一个数字使得两个数字相加是2的d次幂。
做法:由于a[i]<1e9,2的幂次最多32个。map保存数组a[i],暴力枚举2的幂次即可。
D. Polycarp and Div 3
给你一个字符串,问最多分成多少个部分,使得,每个部分的数字和是3的倍数。。
做法:有零的话就单独一个点,否则就记录当前面和模3是1时的位置和模2时的位置。当保存了1,2的位置,然后遇到1,2的位置就与之前的位置算进答案里。同时清楚1,2的位置。。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
const int N=2e5+10;
char s[N];
int a[N];
int vis[10];
int main()
{
cin>>s+1;
int n=strlen(s+1);
for(int i=1;i<=n;++i) a[i]=s[i]-'0';
int sum=0;
int ans=0;
for(int i=1;i<=n;++i)
{
int id=(sum+a[i])%3;
if(id==0)
{
vis[1]=vis[2]=0;
sum=0;
ans++;
continue;
}
if(vis[id])
{
vis[0]=vis[1]=vis[2]=0;
ans++;
sum=0;
}
else vis[id]=i,
sum=(sum+a[i]%3);
}
printf("%d\n",ans);
}
E1. Median on Segments (Permutations Edition)
给一个n,m
n个数,数组a[i]是一个排列。。。
问有多少个区间是以m为中位数。1 2 3 4的中位数是2.
那么计算出m左边每一位上 比m大的个数减去左边比m小的个数之差
右边同理
那么当右边遇到一个t=mx-mi,只需要在右边找一个-t的位置即可。。。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
const int N=2e5+10;
map<ll,int>mp;
int n,m;
int a[N],vis[N];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
{
scanf("%d",&a[i]);
vis[a[i]]=i;
}
int id=vis[m];
int mx=0,mi=0;
for(int i=id+1;i<=n;++i)
{
if(a[i]<m) mx++;
else mi++;
int t=mx-mi;
mp[t]++;
}
mx=mi=0;
ll ans=0;
for(int i=id;i>=1;--i)
{
if(i!=id)
{
if(a[i]<m) mx++;
else mi++;
}
if(i==id) mp[0]++;
int t=-(mx-mi);
ans+=mp[t];
ans+=mp[t-1];
}
printf("%lld\n",ans);
}
注意用longlong,没用longlong wa在50发,这要是打了,我估计又得别hack
F- F题题解见链接: