这场好像是睡过了?罚时是从一小时开始的。。。
题面
注意到数的循环节长度肯定是总长度的约数,枚举循环节长度即可,最后与原数位数 − 1 -1 −1的 99...9 99...9 99...9比较即可。
#include
#define N 200020
#define reg register
using namespace std;
typedef long long ll;
inline void read(ll &x){
ll s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+(ch&15);ch=getchar();}
x=s*w;
}
int T;
ll n,pre[200];
bool vis[N];
int ws(ll n){
int sum=0;
while(n){
sum++,n/=10;
}
return sum;
}
int main(){
cin>>T;
pre[0]=1LL;
for(int i=1;i<=18;i++)pre[i]=pre[i-1]*10LL;
while(T--){
read(n);
int now=ws(n);
ll ans=pre[now-1]-1;
for(int i=1;i<now;i++){
if(now%i!=0)continue;
ll c=1;
for(int j=i;j<now;j+=i)c+=pre[j];
if(pre[i-1]>n/c)continue;
ans=max(ans,n/c*c);
}
printf("%lld\n",ans);
}
}
题面
先将原序列排序,然后看数在原序列和新序列的位置,如果模 k k k相同,那么代表可以交换到,判断所有数即可。
#include
#define N 200020
#define reg register
using namespace std;
typedef long long ll;
inline int read(){
int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+(ch&15);ch=getchar();}
return s*w;
}
int a[N],b[N],vis[N],flag;
int main(){
int n=read(),k=read();
for(int i=1;i<=n;i++)a[i]=b[i]=read();
sort(a+1,a+1+n);
for(int i=1;i<=n;i++){
int r=upper_bound(a+1,a+1+n,b[i])-a-1;
int l=lower_bound(a+1,a+1+n,b[i])-a;
int j=0,p=0;
for(j=l;j<=r&&j<l+k;j++){
if(j%k==i%k)break;
}
for(p=j;p<=r;p+=k){
if(!vis[p]){
vis[p]=1;
break;
}
}
if(j==r+1||p>=r+1){
flag=1;
break;
}
}
if(flag)puts("No");
else puts("Yes");
}
题面
枚举 i i i,并对 i i i质因数分解求出最小能满足 i × j i\times j i×j是完全平方数的 j j j,再对 j j j乘上完全平方数直到 j > n j> n j>n。方案数为 ⌊ n j ⌋ \sqrt{\lfloor\frac{n}{j}\rfloor} ⌊jn⌋。
#include
#define N 200020
#define reg register
using namespace std;
typedef long long ll;
inline void read(int &x){
int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+(ch&15);ch=getchar();}
x=s*w;
}
int n,a[N],prime[N],cnt,ans,s;
bool vis[N];
int main(){
read(n);
for(int i=2;i<=n;i++){
if(!vis[i])prime[++cnt]=i;
for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
vis[i*prime[j]]=true;
if(i%prime[j]==0)break;
}
}
for(int i=1;i<=n;i++){
a[i]=1;
int now=i,flag=0;
for(int j=1;j<=cnt&&prime[j]<=now;j++){
int sum=0;
while(now%prime[j]==0&&now){
sum++,now/=prime[j];
}
if(sum&1)a[i]*=prime[j];
}
ans+=sqrt((n/a[i]));
}
cout<<ans<<endl;
}
题面
签到题,输出两个 o o o之间的曼哈顿距离即可。
#include
#define N 110
#define reg register
using namespace std;
typedef long long ll;
inline void read(int &x){
int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+(ch&15);ch=getchar();}
x=s*w;
}
int n,m,a,b,c,d;
char sqr[N][N];
int main(){
read(n),read(m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
char chr=getchar();
while(chr!='-'&&chr!='o')chr=getchar();
sqr[i][j]=chr;
if(chr=='o'){
if(!a)a=i,b=j;
else c=i,d=j;
}
}
}
cout<<abs(a-c)+abs(b-d)<<endl;
}
题面
维护一个 s e t set set一个 m a p map map,输入一个数如果没出现在 s e t set set那么 s e t , m a p set,map set,map同时插入,设其 m a p map map的对应值为 1 1 1。
每次删除一个数 c c c次,进行判断 m a p map map中对应值是否大于 c c c,大于直接减去 c c c即可,小于在 s e t , m a p set,map set,map中同时删除该数即可。
对于询问,直接输出 s e t set set首尾元素之差即可。
#include
#define N 110
#define reg register
using namespace std;
typedef long long ll;
inline void read(int &x){
int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+(ch&15);ch=getchar();}
x=s*w;
}
int q,op,x,c;
map<int,int> mp;
set<int> s;
int main(){
read(q);
while(q--){
read(op);
if(op==3)printf("%d\n",*s.rbegin()-*s.begin());
if(op==1){
read(x);
if(s.find(x)!=s.end())mp[x]++;
else mp[x]++,s.insert(x);
}
if(op==2){
read(x);read(c);
if(mp[x]<=c){
s.erase(x);
mp.erase(x);
}
else mp[x]-=c;
}
}
}