A. Number of Apartments
//#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
//#define int ll
#define ff first
#define ss second
const int maxn=2e5+10,inf=0x3f3f3f3f,mod=1000000007;
const ll INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-9;ned main(signed argc, char const *argv[])
{
std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int t,n;
cin>>t;
while(t--)
{
cin>>n;
int c0=0,c1=0,c2=0,ok=0;
for(int i=0;i*3<=n;i++)
{
for(int j=0;i*3+j*5<=n;j++)
{
for(int k=0;i*3+j*5+k*7<=n;k++)
{
if(i*3+j*5+k*7==n)
{
ok=1;
c0=i,c1=j,c2=k;
goto label;
}
}
}
}
label:
if(!ok)
cout<<-1<<endl;
else
cout<<c0<<' '<<c1<<' '<<c2<<endl;
}
return 0;
}
B.Barrels
//#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
//#define int ll
#define ff first
#define ss second
const int maxn=2e5+10,inf=0x3f3f3f3f,mod=1000000007;
const ll INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-9;
ll a[maxn];
signed main(signed argc, char const *argv[])
{
std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int t,n,k;
cin>>t;
while(t--)
{
cin>>n>>k;
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+n+1,greater<ll>());
ll ans=0;
for(int i=1;i<=k+1;i++)
ans+=a[i];
cout<<ans<<endl;
}
return 0;
}
C. Numbers on Whiteboard
//#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
//#define int ll
#define ff first
#define ss second
const int maxn=2e5+10,inf=0x3f3f3f3f,mod=1000000007;
const ll INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-9;
int ans[maxn][2];
signed main(signed argc, char const *argv[])
{
std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int t,n;
cin>>t;
while(t--)
{
cin>>n;
int pre=n,now;
ans[1][0]=n,ans[1][1]=n-1;
for(int i=n-1;i>=1;i--)
{
ans[n-i][0]=pre,ans[n-i][1]=i;
pre=(pre+i)/2+(pre+i)%2;
}
cout<<pre<<endl;
for(int i=1;i<n;i++)
cout<<ans[i][0]<<' '<<ans[i][1]<<endl;
}
return 0;
}
D. String Deletion
题意
T T T次询问,对于每一次询问:
给定一个长度为 n n n的01串,每次操作可以选择一个位置 i i i,消除第 i i i位,然后把01串前面连续的一串1或者是一串0消除,求最大操作数。
思路
写了个后缀和+贪心,调到结束都没调出来。
错误的代码贴在这了……
然后看了题解写了双指针+贪心。
思路都是一样的,第一个删除操作尽力在剩余部分靠左删除
//#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
//#define int ll
#define ff first
#define ss second
const int maxn=2e5+10,inf=0x3f3f3f3f,mod=1000000007;
const ll INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-9;
char s[maxn];
signed main(signed argc, char const *argv[])
{
std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int t,n;
cin>>t;
while(t--)
{
cin>>n>>s+1;
int now=1;
vector<int>v;
for(int i=2;i<=n;i++)
{
if(s[i]!=s[i-1])
{
v.push_back(now);
now=0;
}
now++;
}
v.push_back(now);
vector<int>ret(v.size()+1,0);
for(int i=v.size()-1;i>=0;i--)
{//富裕后缀和
ret[i]=ret[i+1]+v[i]-1;
}
int cost=0,ans=v.size();
bool del=0;
for(int i=0;i<v.size();i++)
{
//printf("x=%d,ret[%d]=%d,cost=%d,del=%d\n",v[i],i,ret[i],cost,del);
if(v[i]-2>=cost)
{//清空cost
cost=0;
}
else{
if(v[i]>2)//
cost-=v[i]-2;
else if(del)
{
ans--;
del=0;
continue;
}
else if(v[i]==1)
{
if(cost<ret[i])
cost++;
else
del=1;
}
}
}
cout<<"ans=";
cout<<ans<<endl;
}
return 0;
}
/*
999
10
1110010111
6
111111
9
100100100
4
1001
ans=5,1,5,2
*/
正确的代码
//#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
//#define int ll
const int maxn=2e5+10,inf=0x3f3f3f3f,mod=1000000007;
char s[maxn];
signed main(signed argc, char const *argv[])
{
std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int t,n;
cin>>t;
while(t--)
{
cin>>n>>s+1;
int now=1;
vector<int>v;
for(int i=2;i<=n;i++)
{
if(s[i]!=s[i-1])
{
v.push_back(now);
now=0;
}
now++;
}
v.push_back(now);
int ans=0;
for(int l=0,r=0;l<v.size();l++)
{
if(v[l]>=2)
{//操作1,2都从这里删
ans++;
}
else{//操作1要贪心从下面富裕的部分找
while(r<v.size()&&v[r]==1)
r++;
if(r<v.size()&&v[r]>=2)
v[r]--;
else//从左面删
l++;
ans++;
}
if(r<=l)
r=l+1;
}
cout<<ans<<endl;
}
return 0;
}
E. String Reversal
//#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
//#define int ll
#define ff first
#define ss second
const int maxn=2e5+10,inf=0x3f3f3f3f,mod=1000000007;
struct BinaryIndexedsTree
{
int n;
ll c[maxn],sum[maxn];//c维护差分数组,sum维护i*c[i]的前缀和
inline int lowbit(int x)
{
return x & (-x);
}
void build(int n)//a是原数组,n是元素个数
{
this->n=n;
memset(c,0,sizeof(c));
memset(sum,0,sizeof(sum));
// for(int i=1;i<=n;i++)
// add(i,a[i]-a[i-1]);//构建差分c数组
}
void add(int k,ll val)//修改:a[k]加上val,直接在c数组上操作
{//请使用区间更新
for(int i=k;i<=n;i+=lowbit(i))//从叶子一直更新到父节点
c[i]+=val,sum[i]+=val*(k-1);//每个节点都加上val
}
void radd(int l,int r,ll val)//区间更新
{
add(l,val);//把l之后所有的点都更新一遍
add(r+1,-val);//因为r之后的点是不用更新的,但是多更新了,所以要每个点都-val;
}
ll query(int k)//查询:c[i]前缀和的前缀和,即a[i]的前缀和
{//节点i的长度为lowbit(i)
ll ret=0;
for(int i=k;i;i-=lowbit(i))
ret+=k*c[i]-sum[i];
return ret;
}
} bit;
char s[maxn];
signed main(signed argc, char const *argv[])
{
std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int n;
cin>>n>>s+1;
bit.build(n);
vector<int>st[30],p(27,0);
for(int i=1;i<=n;i++)
st[s[i]-'a'].push_back(i);
ll ans=0;
for(int i=1;i<=n;i++)
{
int id=s[n-i+1]-'a';
int pos=st[id][p[id]++];
ans+=bit.query(n)-bit.query(pos);
bit.radd(pos,pos,1);
}
cout<<ans<<endl;
return 0;
}