这是一场失败的比赛。
前三题应该是随便搞的。
D有点想法,一直死磕D,一直WA。(赛后发现少减了个1……)
看E那么多人过了,猜了个结论交了真过了。
感觉这次升的不光彩……还是等GR3掉了洗掉这次把,,,
A
水题,对于每个首字母分成一半一半即可。
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> PII; const int maxn=100010; #define MP make_pair #define PB push_back #define lson o<<1,l,mid #define rson o<<1|1,mid+1,r #define FOR(i,a,b) for(int i=(a);i<=(b);i++) #define ROF(i,a,b) for(int i=(a);i>=(b);i--) #define MEM(x,v) memset(x,v,sizeof(x)) inline ll read(){ char ch=getchar();ll x=0,f=0; while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar(); while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar(); return f?-x:x; } int n,cnt[26],ans; char s[25]; int main(){ n=read(); FOR(i,1,n) scanf("%s",s+1),cnt[s[1]-'a']++; FOR(i,0,25){ int x=cnt[i]/2,y=cnt[i]-x; ans+=x*(x-1)/2+y*(y-1)/2; } printf("%d ",ans); }
B
水题。首先行列长度都要 $ge 5$,然后就可以随便搞了。
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> PII; const int maxn=100010; #define MP make_pair #define PB push_back #define lson o<<1,l,mid #define rson o<<1|1,mid+1,r #define FOR(i,a,b) for(int i=(a);i<=(b);i++) #define ROF(i,a,b) for(int i=(a);i>=(b);i--) #define MEM(x,v) memset(x,v,sizeof(x)) inline ll read(){ char ch=getchar();ll x=0,f=0; while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar(); while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar(); return f?-x:x; } int n,sq,x,y; int main(){ n=read(); for(int i=2;i*i<=n;i++) if(n%i==0) x=i,y=n/i; if(x<5 || y<5) return puts("-1"),0; FOR(i,1,x){ if(i%5==1){ printf("aeiou"); FOR(j,1,y-5) printf("a"); } if(i%5==2){ printf("eioua"); FOR(j,1,y-5) printf("e"); } if(i%5==3){ printf("iouae"); FOR(j,1,y-5) printf("i"); } if(i%5==4){ printf("ouaei"); FOR(j,1,y-5) printf("o"); } if(i%5==0){ printf("uaeio"); FOR(j,1,y-5) printf("u"); } } }
C
比较水的一题。
发现把 $a$ 变成 $-a$ 不影响答案($|a-b|$ 变成 $|a+b|$,$|a+b|$ 变成 $|a-b|$)。
那么全变成非负数,枚举较小那个,随便统计一下即可。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=200020; #define FOR(i,a,b) for(int i=(a);i<=(b);i++) #define ROF(i,a,b) for(int i=(a);i>=(b);i--) #define MEM(x,v) memset(x,v,sizeof(x)) inline ll read(){ char ch=getchar();ll x=0,f=0; while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar(); while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar(); return f?-x:x; } int n,a[maxn]; ll ans; inline int binary(int x){return lower_bound(a+1,a+n+1,x)-a;} int main(){ n=read(); FOR(i,1,n) a[i]=abs(read()); sort(a+1,a+n+1); FOR(i,1,n){ int p=upper_bound(a+1,a+n+1,2*a[i])-a; if(p>n) p=n; if(a[p]>2*a[i]) p--; ans+=p-i; } cout<<ans; }
D
思路上也不是什么难题。但是代码打着真的难受……
枚举答案序列的长度 $k$(先特判 $k=1$ 和 $k=2$ 可不可行,避免一堆讨论)
经过推式子发现 $b=2^{k-2}a+2^{k-3}r_2+2^{k-4}r_3+dots+2r_{k-2}+r_{k-1}+r_k$。
从前往后考虑 $r_i(2le ile k-2)$ 是什么。发现 $r_{i+1}$ 到 $r_n$ 能组成的数最大是 $2^{k-i-1}m$,最小是 $2^{k-i-1}$,而且这之间的数都能被表示出来。
解个方程,$dfrac{s}{2^{k-i-1}}-mle xle dfrac{s}{2^{k-i-1}}-1$。任取一个合法的数即可。($s$ 是 $b$ 与目前的和的差)
最后 $r_{k-1}+r_k=s$,随便分配一下就行了。
现实很骨感。
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define FOR(i,a,b) for(int i=(a);i<=(b);i++) #define ROF(i,a,b) for(int i=(a);i>=(b);i--) #define MEM(x,v) memset(x,v,sizeof(x)) inline ll read(){ char ch=getchar();ll x=0,f=0; while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar(); while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar(); return f?-x:x; } int q; ll a,b,m,r[55],p2[55]; int main(){ p2[0]=1; FOR(i,1,50) p2[i]=2*p2[i-1]; q=read(); while(q--){ a=read();b=read();m=read(); MEM(r,0); if(a==b) cout<<1<<" "<<a<<endl; else if(b-a<=m) cout<<2<<" "<<a<<" "<<b<<endl; else{ bool flag=false; FOR(k,3,50){ if(p2[k-2]<ceil(1.0*b/(a+m)) || p2[k-2]>b/(a+1)) continue; ll s=b-p2[k-2]*a; bool ok=true; FOR(i,2,k-2){ ll upr=1.0*s/p2[k-i-1]-1,lwr=ceil(1.0*s/p2[k-i-1])-m; r[i]=min(upr,m); if(r[i]<lwr){ok=false;break;} s-=p2[k-i-1]*r[i]; } if(!ok) continue; r[k-1]=min(m,s-1); r[k]=s-r[k-1]; if(r[k]>m) continue; flag=true; ll s2=s=a; cout<<k<<" "<<s<<" "; FOR(i,2,k){ s=s2+r[i]; cout<<s<<" "; s2+=s; } cout<<endl; break; } if(!flag) puts("-1"); } } }
E
%%%zz猜结论神仙
令第 $i$ 天的限制集合为 $S_i$。
首先发现,如果有两天的集合没有交,那么有 $operatorname{lcm}{S_i}>operatorname{lcm}{U-S_i}ge operatorname{lcm}{S_j}>operatorname{lcm}{U-S_j}geoperatorname{lcm}{S_i}$,不可能成立。
下面证明如果任意两天集合都有交那么一定有解。
任取 $m$ 个不同的质数 $p_i$。
一开始令 $a_i=1$,接下来如果第 $j$ 天买了第 $i$ 个,那么 $a_i*=p_j$。
那么 $operatorname{lcm}{S_i}=prod p_j$。因为 $S_i$ 与其它所有 $S$ 都有交,所以其中的元素一定乘了所有的 $p_i$。
同时 $U-S_i$ 中所有元素都没有乘过 $p_i$,所以 $operatorname{lcm}{U-S_i}leprod_{i e j}p_j<prod p_j=operatorname{lcm}{S_i}$。
证毕。
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> PII; const int maxn=100010; #define MP make_pair #define PB push_back #define lson o<<1,l,mid #define rson o<<1|1,mid+1,r #define FOR(i,a,b) for(int i=(a);i<=(b);i++) #define ROF(i,a,b) for(int i=(a);i>=(b);i--) #define MEM(x,v) memset(x,v,sizeof(x)) inline ll read(){ char ch=getchar();ll x=0,f=0; while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar(); while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar(); return f?-x:x; } int m,n,s[55]; bool ss[55][10010]; int main(){ m=read();n=read(); FOR(i,1,m){ s[i]=read(); FOR(j,1,s[i]) ss[i][read()]=true; FOR(j,1,i-1){ int cnt=0; FOR(k,1,n) if(ss[i][k] && ss[j][k]) cnt++; if(!cnt) return puts("impossible"),0; } } puts("possible"); }
F
看起来是个大数据结构,以后再来搞吧。