题解——牛客网OI赛制测试赛2
T1
规律题
考虑先全部选中再去重即可
#include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; int barrel[10010]={0}; int main(){ int T; scanf("%d",&T); for(int tt=1;tt<=T;tt++){ int cnta=0,cntb=0,cnt=0,ans=0; int a,b; scanf("%d %d",&a,&b); for(int i=1;i<=sqrt(a);i++){ if(a%i==0){ if(i!=a/i){ barrel[i]=tt; barrel[a/i]=tt; cnta+=2; } else{ barrel[i]=tt; cnta+=1; } } } // printf("%d\n",cnta); for(int i=1;i<=sqrt(b);i++){ if(b%i==0){ if(i!=b/i){ cntb+=2; } else{ cntb+=1; } if(i!=b/i){ if(barrel[i]==tt){ cnt++;} if(barrel[b/i]==tt){ cnt++;}} else{ if(barrel[i]==tt){ cnt++;} } } } // printf("%d\n",cnt); ans+=cnta*cntb-(cnt)*(cnt-1)/2; printf("%d\n",ans); } return 0; }
T2
科技题
考试的时候完全不知道有传递闭包的黑科技
可以解决比如\( a \) 和\( b \)是否联通
\( a\)到\( b \)有多少条长度为k的路径的问题
有Floyd和矩阵快速幂两种解法
比较有趣
然后记得开long long
#include <cstdio> #include <algorithm> #include <cstring> #include <queue> #define int long long using namespace std; int n,k; struct Matrix{ static const int MAXN = 100; int alpha[MAXN][MAXN]; int n,m; void init2(void){ for(int i=0;i<MAXN;i++) for(int j=0;j<MAXN;j++) alpha[i][j]=0; n=m=0; } void init(int x){ for(int i=1;i<=x;i++) alpha[i][i]=1; n=m=x; } Matrix operator *(Matrix b){ Matrix tmp; tmp.init2(); for(int i=1;i<=n;i++) for(int j=1;j<=b.m;j++) for(int k=1;k<=m;k++) tmp.alpha[i][j]+=alpha[i][k]*b.alpha[k][j]; tmp.n=n; tmp.m=b.m; return tmp; } }; Matrix pow(Matrix a,int p){ Matrix ans; ans.init2(); ans.init(a.n); while(p){ if(p&1) ans=ans*a; a=a*a; p>>=1; } return ans; } signed main(){ scanf("%lld %lld",&n,&k); Matrix a; a.init2(); a.m=a.n=n; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%lld",&a.alpha[i][j]); Matrix b=pow(a,k); printf("%lld",b.alpha[1][n]); return 0; }
T3
单调栈经典应用,随手一码即可
#include <cstdio> #include <algorithm> #include <cstring> #include <stack> using namespace std; struct Node{ int pos,x; }; stack<Node> S; int a[10010],n,b[10010]; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++){ while((!S.empty())&&a[i]>S.top().x){ b[S.top().pos]=i; S.pop(); } S.push(Node{i,a[i]}); } while(!S.empty()){ b[S.top().pos]=0; S.pop(); } for(int i=1;i<=n;i++) printf("%d ",b[i]); return 0; }
T4
瞪眼打表出轨率OR玄学证明一下?
也是规律题
记得long long
#include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #define int long long using namespace std; int n; signed main(){ scanf("%lld",&n); if(n==1) printf("1"); else printf("%lld",(int)sqrt(n) ); return 0; }
T5
结论题
扫一遍统计一下有多少不匹配就可以了
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; int l=0,rno=0,n; bool get(void){ char c=getchar(); while(c!='('&&c!=')') c=getchar(); if(c=='(') return true; else return false; } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ if(get()){ l+=1; } else{ if(l) l--; else rno++; } } if(rno==0) printf("0"); else printf("%d",(rno%2)?(rno/2+1):(rno/2)); return 0; }
T6
貌似提交答案?
手动二分+Ruby求阶乘打表qwq
还打错了一个
#include <cstdio> #include <algorithm> #include <cstring> #include <string> #include <iostream> using namespace std; long long n; int main(){ cin>>n; if(n==7) printf("10\n"); if(n==77) printf("94\n"); if(n==777) printf("892\n"); if(n==7777) printf("8640\n"); if(n==77777) printf("84657\n"); if(n==777777) printf("834966\n"); if(n==7777777) printf("8267019\n"); if(n==77777777) printf("82052137\n"); if(n==777777777) printf("815725636\n"); if(n==7777777777) printf("8118965902\n"); return 0; }