清北刷题冲刺 11-01 a.m
立方体
/* 输入数据中的p的位置是没有用的,而题目本质上是求C(n,k) */ #include<iostream> #include<cstdio> #define mod 1000000007 #define maxn 1000001 using namespace std; int n,k,x; long long fac[maxn]={1,1},inv[maxn]={1,1},f[maxn]={1,1}; long long C(long long a,long long b){ return fac[a]*inv[b]%mod*inv[a-b]%mod; } void prepare(){ for(int i=2;i<maxn;i++){ fac[i]=fac[i-1]*i%mod; f[i]=(mod-mod/i)*f[mod%i]%mod; inv[i]=inv[i-1]*f[i]%mod; } } int main(){ freopen("cube.in","r",stdin);freopen("cube.out","w",stdout); scanf("%d%d",&n,&k); prepare(); for(int i=1;i<=n;i++)scanf("%d",&x); cout<<C(n,k); return 0; }
仓库
/* 跑一遍最大生成树,把边权存下来,然后排个序 每次询问只需要找小于w的辺权的个数加一即可 查找的时候用二分 */ #include<iostream> #include<cstdio> #include<algorithm> #define maxn 100010 using namespace std; int n,m,q,a[maxn],cnt,fa[maxn]; struct Node{ int x,y,v; }E[maxn]; int query(int x){ int l=0,r=n-1,res=0; while(l<=r){ int mid=(l+r)>>1; if(a[mid]<x)res=mid,l=mid+1; else r=mid-1; } return res; } bool cmp(Node x,Node y){return x.v>y.v;} int find(int x){ if(x==fa[x])return x; return fa[x]=find(fa[x]); } int main(){ // freopen("Cola.txt","r",stdin); freopen("warehouse.in","r",stdin);freopen("warehouse.out","w",stdout); scanf("%d%d%d",&n,&m,&q); for(int i=1;i<=n;i++)fa[i]=i; int x,y; for(int i=1;i<=m;i++)scanf("%d%d%d",&E[i].x,&E[i].y,&E[i].v); sort(E+1,E+m+1,cmp); for(int i=1;i<=m;i++){ int f1=find(E[i].x),f2=find(E[i].y); if(f1==f2)continue; fa[f1]=f2; a[++cnt]=E[i].v; if(cnt==n-1)break; } sort(a+1,a+cnt+1); while(q--){ scanf("%d",&x); int pos=query(x); pos+=1; printf("%d\n",pos); } return 0; }
单词
#include<iostream> #include<cstdio> #include<cstring> #include<map> #define maxn 1010 using namespace std; int n,q,len[maxn],L; string s[maxn]; map<string,bool>vis; int main(){ freopen("word.in","r",stdin);freopen("word.out","w",stdout); // freopen("Cola.txt","r",stdin); scanf("%d%d",&n,&q); for(int i=1;i<=n;i++){ cin>>s[i]; len[i]=s[i].length(); } while(q--){ scanf("%d",&L); vis.clear(); long long ans=0; for(int i=1;i<=n;i++){ if(len[i]==L){ ans++; vis[s[i]]=1; } } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(len[i]+len[j]<L)continue; string snow=""; for(int l1=max(1,L-len[j]);l1<=min(len[i],L-1);l1++){//枚举用第一个字符串的多长 snow="";int l2=L-l1; snow+=s[i].substr(0,l1); snow+=s[j].substr(len[j]-l2,l2); if(!vis[snow]){ vis[snow]=1; ans++; } } } } printf("%d\n",ans); } }
预计得分100+100+0 实际得分100+100+0 今天的T1T2特别简单,T3一开始以为是Trie树,但是后来不太会做,就直接写的暴力,复杂度很高,map常熟又特别大,所以估分为0 今天早上迟到了,心情比较焦躁,但是T1特别简单,所以没有耽误很多时间