Codeforcess
A
暴力枚单个循环节
code:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define C getchar()-48
inline ll read()
{
ll s=0,r=1;
char c=C;
for(;c<0||c>9;c=C) if(c==-3) r=-1;
for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
return s*r;
}
int t,la;
char a[80],b[80]={'Y','e','s','Y','e','s','Y','e','s','Y','e','s'};
int main()
{
t=read();
while(t--)
{
scanf("%s",a+1);la=strlen(a+1);
int pd=0;
for(int k=0;k<=2;k++)
{
int tmppd=1;
for(int i=1;i<=la;i++) if(a[i]!=b[(i+k)%3]) tmppd=0;
pd|=tmppd;
}
if(pd==1) puts("YES");
else puts("NO");
}
return 0;
}
B
从小到大暴力枚举,累加上没出现的,判断是否合法
code:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define C getchar()-48
inline ll read()
{
ll s=0,r=1;
char c=C;
for(;c<0||c>9;c=C) if(c==-3) r=-1;
for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
return s*r;
}
const int N=110,M=3e5+10;
int t;
int m,s,sum;
int mp[M+10],a[N];
#define p1 puts("YES")
#define p2 puts("NO")
int main()
{
t=read();
int tmpsum=0;
for(int i=1;i<=100;i++) tmpsum+=i,mp[tmpsum]=1;
while(t--)
{
m=read(),s=read();sum=0;int pd=1;
for(int i=1;i<=m;i++) a[i]=read(),sum+=a[i];
sort(a+1,a+1+m);
if(!mp[sum+s]){p2;continue;}
int tmpsum=sum+s,del=1;
while(tmpsum>0) tmpsum-=del++;
if(tmpsum==0&&del>a[m]){p1;continue;}
else{p2;continue;}
}
return 0;
}
C
经典做法,贪心。将区间的可行情况转化为两个端点进行讨论。
一个点一定范围之外才能走,对于一个区间,如果能走进区间,那么显然能走到两端点其中之一。
如果区间内两点可走,那么两端点必然相互可走。
以区间的两端点为媒介进行走,判断起点终点与两端点的可走情况,讨论出步数。
当时具体地考虑每种情况真是太蠢了,要先考虑优化。
code:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define int ll
const int MaxN=2e5+100;
int N,M,T,L,R,x,a,b;
template<class T>
inline void qread(T &sum)
{
sum=0;int boo=1;
char x=getchar();
while(x<'0'||x>'9'){if(x=='-')boo=-1;x=getchar();}
while(x>='0'&&x<='9'){sum=(sum<<1)+(sum<<3)+x-'0';x=getchar();}
sum*=boo;
}
template<class T>
void qput(T x)
{
if(x<0) {x=-x;putchar('-');}
if(x>9){qput(x/10);}
putchar(x%10+48);
}
inline void Solve()
{
qread(L);qread(R);qread(x);
qread(a);qread(b);
if(a==b)
{
qput(0);putchar('\n');return;
}
if(b>R||b<L)
{
qput(-1);putchar('\n');return;
}
if(abs(b-a)>=x)
{
qput(1);putchar('\n');return;
}
if(abs(a-L)>=x&&abs(b-L)>=x)
{
qput(2);putchar('\n');return;
}
if(abs(a-R)>=x&&abs(b-R)>=x)
{
qput(2);putchar('\n');return;
}
if(abs(R-a)>=x&&abs(L-b)>=x)
{
qput(3);putchar('\n');return;
}
if(abs(L-a)>=x&&abs(R-b)>=x)
{
qput(3);putchar('\n');return;
}
qput(-1);putchar('\n');return;
}
signed main()
{
qread(T);
while(T--) Solve();
}
C
求a*b
后缀0最多,b<=c, a,c
相乘结果为10
,只有10
,2
,5
,1
的情况。
先提因数10
,再提2
,5
。
b中能用2
,5
消掉a
的,尽量用,因为消耗小,再尽量用10
code:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define C getchar()-48
inline ll read()
{
ll s=0,r=1;
char c=C;
for(;c<0||c>9;c=C) if(c==-3) r=-1;
for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
return s*r;
}
const ll inf=1e9;
int t;
ll n,m;
inline void work()
{
n=read(),m=read();ll tmpn=n;
ll gs2=0,gs5=0,ans=0,sum2=1,sum5=1;
while(n%10==0) n/=10;
while(n%2==0) n/=2,gs2++,sum2*=5;
while(n%5==0) n/=5,gs5++,sum5*=2;
if(gs2)
{
for(ll i=inf;i>=1;i/=10) if(m>=sum2*i)
{
printf("%lld\n",(m/(sum2*i))*(sum2*i)*tmpn);
return;
}
ans=1;
while(ans*5<=m) ans*=5;
printf("%lld\n",(m/(ans))*(ans)*tmpn);
return;
}
if(gs5)
{
for(ll i=inf;i>=1;i/=10) if(m>=sum5*i)
{
printf("%lld\n",(m/(sum5*i))*(sum5*i)*tmpn);
return;
}
ans=1;
while(ans*2<=m) ans*=2;
printf("%lld\n",(m/(ans))*(ans)*tmpn);
return;
}
for(ll i=inf;i>=1;i/=10) if(m>=i)
{
printf("%lld\n",(m/(i))*(i)*tmpn);
return;
}
}
int main()
{
t=read();
while(t--) work();
return 0;
}
E
暴力枚举使用223,232,322情况,不够就喝药
code:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define C getchar()-48
inline ll read()
{
ll s=0,r=1;
char c=C;
for(;c<0||c>9;c=C) if(c==-3) r=-1;
for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
return s*r;
}
const ll N=2e5+10;
ll t;
ll n,h,gs;
ll a[N];
inline void tj(ll v1,ll v2,ll v3)
{
ll tmpgs,tmpsum,cs;
tmpgs=0,tmpsum=h,cs=0;
for(ll i=1;i<=n;i++)
{
while(a[i]>=tmpsum&&cs<3)
{
if(cs==0) tmpsum*=v1;
if(cs==1) tmpsum*=v2 ;
if(cs==2) tmpsum*=v3;
cs++;
}
if(a[i]<tmpsum)
{
tmpgs++;
tmpsum+=a[i]/2;
}
}
gs=max(gs,tmpgs);
}
inline void work()
{
n=read(),h=read();gs=0;
for(ll i=1;i<=n;i++) a[i]=read();
sort(a+1,a+1+n);
tj(2,2,3);tj(2,3,2);tj(3,2,2);
cout<<gs<<endl;
}
int main()
{
t=read();
while(t--) work();
return 0;
}
F
最多p-1次,倒数第二位最多进1,直接讨论
code:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define C getchar()-48
inline ll read()
{
ll s=0,r=1;
char c=C;
for(;c<0||c>9;c=C) if(c==-3) r=-1;
for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
return s*r;
}
const ll N=2e5+10,inf=1e9+7;
ll t,lb;
ll n,p;
ll a[N],b[N];
inline void work()
{
n=read(),p=read();
for(int i=1;i<=n;i++) a[i]=b[i]=read();
sort(b+1,b+1+n);
lb=unique(b+1,b+1+n)-(b+1);
int tmpr=lb,tmpl=1,mxr=p,mnl=-1;
while(tmpr>=1&&b[tmpr]==mxr-1) mxr--,tmpr--;
while(tmpl<=lb&&b[tmpl]==mnl+1) mnl++,tmpl++;
if(mxr==0){puts("0");return;}
if(mnl>=a[n]-1){cout<<mxr-(a[n])-1<<endl;return;}
int ans=p-a[n];b[++lb]=0;
int tmpw=n-1;
while(tmpw>=1&&a[tmpw]==p-1) tmpw--;
b[++lb]=a[tmpw]+1;
sort(b+1,b+1+lb);
lb=unique(b+1,b+1+lb)-(b+1);
tmpl=1,mxr=a[n]+1,mnl=-1;
for(tmpr=lb;tmpr;tmpr--) if(b[tmpr]==a[n]) break;
while(tmpr>=1&&b[tmpr]==mxr-1) mxr--,tmpr--;
cout<<ans+max(0,mxr-1)<<endl;
}
int main()
{
t=read();
while(t--) work();
return 0;
}
F
倒着做,用平衡树或者set维护比bi小剩余最大的值
code:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define C getchar()-48
inline ll read()
{
ll s=0,r=1;
char c=C;
for(;c<0||c>9;c=C) if(c==-3) r=-1;
for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
return s*r;
}
const int N=2e5+10;
int t;
int n,topt,rt;
int a[N],map[N],vis[N];
int ans[N],topq,askans;
struct xin{
int l,r,v;
double key;
}tr[N<<2];
inline int crt(int v)
{
tr[++topt].v=v;
tr[topt].l=tr[topt].r=0;
tr[topt].key=rand();
return topt;
}
inline void spilt(int x,int v,int &rtl,int &rtr)
{
if(!x){rtl=rtr=0;return;}
if(tr[x].v<=v)
{
rtl=x;
spilt(tr[x].r,v,tr[x].r,rtr);
}
else
{
rtr=x;
spilt(tr[x].l,v,rtl,tr[x].l);
}
}
inline int merge(int x,int y)
{
if(!x||!y) return x|y;
if(tr[x].key<=tr[y].key)
{
tr[x].r=merge(tr[x].r,y);
return x;
}
else
{
tr[y].l=merge(x,tr[y].l);
return y;
}
}
inline void add(int v)
{
int x,y,z;
z=crt(v);
spilt(rt,v,x,y);
rt=merge(merge(x,z),y);
}
inline void del(int v)
{
int x,y,z;
spilt(rt,v,x,y);
spilt(x,v-1,x,z);
z=merge(tr[z].l,tr[z].r);
rt=merge(merge(x,z),y);
}
inline void ask(int x,int v)
{
if(!x) return;
if(tr[x].v<=v)
{
askans=max(askans,tr[x].v);
ask(tr[x].r,v);
}
else ask(tr[x].l,v);
}
inline void work()
{
topt=0;rt=0;tr[rt].l=tr[rt].r=0;
for(int i=1,edi=n/2;i<=edi;i++) vis[a[i]]=0;
n=read();
for(int i=1,edi=n/2;i<=edi;i++) a[i]=read(),vis[a[i]]++;
for(int i=1,edi=n/2;i<=edi;i++) if(vis[a[i]]>1){puts("-1");return;}
for(int i=1;i<=n;i++) add(i);
for(int i=1;i<=n/2;i++) del(a[i]);
for(int i=n/2;i>=1;i--)
{
askans=0;ask(rt,a[i]);
if(!askans){puts("-1");return;}
ans[i*2]=a[i];
ans[i*2-1]=askans;
del(askans);
}
for(int i=1;i<=n;i++) cout<<ans[i]<<" ";puts("");
}
int main()
{
srand(time(0));
t=read();
while(t--) work();
return 0;
}