第13届 广工校赛 题解汇总

题目链接:13届广工校赛

貌似牛客网的算法群里已经有题解的pdf了,那我不复述那么多了。 贴贴AC代码就走~~


A-跳台阶

#include <cstdio>
using namespace std;
 
int n;
long long a[40];
int main(){
    a[1] = 1;
    for (int i=2; i<=30; i++) {
        a[i] = 1;
        for (int j=1; j<i; j++) a[i] += a[j];
    }
    int T;
    scanf("%d",&T);
    while (T--) {
        scanf("%d",&n);
        printf("%lld\n",a[n]);
    }
    return 0;
}


B-跳一跳,很简单的

额,这题代码不是我自己写出来的,编程技巧上我还不够火候。仿照某位大神写出来的,多谢大神的代码share

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;

typedef long long LL;
const int maxn = 1e5+1;
const int maxc = 26;
const int mod = 1e9+7;
const int seed = 29;
const int maxd = 17;

int n,Q;
int a[maxn],b[maxn],pw[maxn];
int dep[maxn],fa[maxd][maxn];
int h[maxc+1][maxn];
vector<int> e[maxn];


void init(){
   pw[0] = 1;
   for (int i=1; i<maxn; i++) pw[i] = (LL)pw[i-1]*seed%mod;
}

void DFS(int u){
     int v;
     for (int i=0; i<e[u].size(); i++) {
         v = e[u][i];
         dep[v] = dep[u]+1;
         int ch = a[v];
         for (int i=0; i<maxc; i++, (ch+=b[v])>=maxc && (ch-=maxc) )
            h[i][v] = ((LL)h[i][u]*seed + ch)%mod;
         DFS(v);
     }
}

inline int Min(int x, int y) {return x<y?x:y; }

int main(){
    int T;
    scanf("%d",&T);
    init();

    while (T--){
       scanf("%d",&n);
       for (int i=0; i<=n; i++) e[i].clear();
       memset(h,0,sizeof(h));

       char op[2];
       for (int i=2; i<=n; i++) {
          scanf("%d%s%d",&fa[0][i],op,&b[i]);
          e[fa[0][i]].push_back(i);
          a[i] = op[0] - 'a';
          b[i] %= maxc;
       }

       for (int i=1; 1<<i <= n; i++) {
           for (int j=1; j<=n; j++) fa[i][j] = fa[i-1][fa[i-1][j]];
       }

       dep[1] = 0;
       DFS(1);

       int u,v,w;
       int uh,vh;
       int uc,vc;
       scanf("%d",&Q);
       while (Q--) {
            scanf("%d%d%d",&u,&v,&w);
            w %= maxc;

            for (int i=maxd-1; i>=0; i--) {
                if (Min(dep[u],dep[v]) < 1<<i) continue;
                uh = (h[w][u] - (LL)h[w][fa[i][u]]*pw[1<<i])%mod;
                vh = (h[w][v] - (LL)h[w][fa[i][v]]*pw[1<<i])%mod;
                if (uh<0) uh += mod;
                if (vh<0) vh += mod;
                if (uh == vh) {
                    u = fa[i][u];
                    v = fa[i][v];
                }
            }

            uc = (a[u] + w*b[u]) % maxc;
            vc = (a[v] + w*b[v]) % maxc;
            if (uc<vc) printf("<\n");
            else if (uc == vc) printf("=\n");
            else printf(">\n");

       }

    }
    return 0;
}


C-平分游戏

正解讲的不太好,推荐一个很好的blog:点击打开链接

注: n == k 的情况应该直接输出gg吧,但加上这句我就gg了。。 去掉之后AC了。。

#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;

typedef long long LL;
const int maxn = 1e6+5;
bool vis[maxn];
LL a[maxn];
LL sum,avg,ans;
int n,k;
vector<LL>g;
bool flag;

LL cal(){
   int sz = g.size();
   g[sz-1] = 0;
   sort(g.begin(),g.end());
   return g[sz/2];
}

int main(){
    while (scanf("%d%d",&n,&k)==2) {
       // if (n == k) { printf("gg\n"); continue; }
        k = min(n-1,k);

        flag = 1;
        sum = 0; ans = 0;
        for (int i=0; i<n; i++) {
            scanf("%lld",&a[i]);
            sum += a[i];
        }
        avg = sum / n;
        if (sum%n) {
            printf("gg\n");
            continue;
        }

        memset(vis,0,sizeof(vis));
        for (int i=0; i<n; i++) if (!vis[i]) {
            LL t = 0, p = 0;
            int pt = i;
            g.clear();
            while (!vis[pt]) {
                g.push_back(a[pt]-avg+p);
                p = g[g.size()-1];
                vis[pt] = 1;
                t += a[pt];
                pt = (pt+k+1)%n;
            }

            int sz = g.size();
            if (t/sz!=avg || t%sz) {
                flag = 0;
                break;
            }

            LL mid = cal();
            for (int k=0; k<sz; k++) ans += abs(mid-g[k]);
        }
        if (!flag) printf("gg\n"); else printf("%lld\n",ans);
    }
    return 0;
}


D-psd面试

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
 
const int maxn = 1500;
int dp[maxn][maxn];
char s[maxn];
int n;
 
int main(){
    while (scanf("%s",s)==1) {
        n = strlen(s);
        memset(dp,0,sizeof(dp));
        for (int i=0; i<n; i++) if (s[i]>='A' && s[i]<='Z') s[i] = s[i]-'A'+'a';
 
        for (int i=0; i<n; i++) dp[i][i] = 1;
        for (int i=1; i<n; i++) {
            int t = 0;
            for (int j=0; j+i<n; j++) {
                if (s[j] == s[j+i]) t = dp[j+1][j+i-1]+2;
                else t = max(dp[j+1][j+i],dp[j][j+i-1]);
                dp[j][j+i] = t;
            }
        }
 
        printf("%d\n",n-dp[0][n-1]);
    }
    return 0;
}


E-回旋星空

#include <cstdio>
#include <algorithm>
using namespace std;
 
const int maxn = 1000+10;
struct Point{
    int x,y;
}p[maxn];
 
int n,ans;
int x,y;
int d[maxn];
 
int main(){
    int T;
    scanf("%d",&T);
    while (T--){
        scanf("%d",&n);
        for (int i=1; i<=n; i++) scanf("%d%d",&p[i].x,&p[i].y);
 
        ans = 0;
        for (int i=1; i<=n; i++) {
           x = p[i].x;
           y = p[i].y;
           for (int j=1; j<=n; j++) d[j] = (x-p[j].x)*(x-p[j].x) + (y-p[j].y)*(y-p[j].y);
           sort(d+1,d+n+1);
           int pt = 1;
           for (int j=2; j<=n; j++) if (d[pt]==d[j]) ans++; else pt = j;
        }
 
        if (ans==0) printf("WA\n"); else printf("%d\n",ans*2);
    }
    return 0;
}


F-等式

#include <cstdio>
#include <cstring>
using namespace std;
 
const int maxn = 70;
int a[maxn],tot;
int ans,n;
 
int main(){
    int T;
    scanf("%d",&T);
    while (T--) {
        scanf("%d",&n);
        tot = 0;
        memset(a,0,sizeof(a));
        for (int i=2; i*i<=n; i++) if (n%i==0) {
            while (n%i==0) a[tot]++, n/=i;
            tot++;
        }
        if (n>1) a[tot++]++;
 
        for (int i=0; i<tot; i++) a[i]<<=1;
        ans = 1;
        for (int i=0; i<tot; i++) ans *= (a[i]+1);
        printf("%d\n",(ans+1)/2);
    }
    return 0;
}


G-旋转矩阵

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;
 
const int maxL = 10000;
const int maxn = 40;
char s[maxn][maxn];
int n,m;
char str[maxL];
stack<int>st;
 
int main(){
    int T;
    scanf("%d",&T);
    while (T--){
        scanf("%d%d",&n,&m);
        for (int i=1; i<=n; i++) scanf("%s",s[i]+1);
        while (!st.empty()) st.pop();
        scanf("%s",str);
        int len = strlen(str);
        for (int i=0; i<len; i++) {
            if (st.empty()) {
                if (str[i]=='L') st.push(0); else st.push(1);
                continue;
            }
            if (st.top()==0 && str[i]=='R')  { st.pop(); continue; }
            if (st.top()==1 && str[i]=='L')  { st.pop(); continue; }
            if (str[i]=='L') st.push(0); else st.push(1);
        }
        int sz = st.size();
        sz %= 4;
 
        if (sz == 0) {
            printf("%d %d\n",n,m);
            for (int i=1; i<=n; i++) printf("%s\n",s[i]+1);
            printf("\n");
            continue;
        }
 
        if (sz == 1 || sz == 3) {
            for (int i=1; i<=n; i++)
            for (int j=1; j<=m; j++) {
                if (s[i][j]=='-') s[i][j] = '|';
                else if (s[i][j]=='|') s[i][j] = '-';
            }
        }
 
        if (sz == 2) {
            printf("%d %d\n",n,m);
            for (int i=n; i>=1; i--)  {
                for (int j=m; j>=1; j--) printf("%c",s[i][j]);
                printf("\n");
            }
            printf("\n");
            continue;
        }
 
        printf("%d %d\n",m,n);
        if (st.top()==0 && sz==1 || st.top()==1 && sz==3) {
               for (int j=m; j>=1; j--) {
                  for (int i=1; i<=n; i++) printf("%c",s[i][j]);
                  printf("\n");
               }
               printf("\n");
               continue;
        }
 
        for (int j=1; j<=m; j++) {
            for (int i=n; i>=1; i--) printf("%c",s[i][j]);
            printf("\n");
        }
        printf("\n");
    }
    return 0;
}


H-哲哲的疑惑

正解的数学变换非常复杂,我是看不懂了。。

推荐一个博客,讲述的不错,虽然思维跳跃大,但能直观的知道最后结果是怎么来的。

点击打开链接

#include <cstdio>
#include <cstring>
using namespace std;

typedef long long LL;
LL n,m,l;
const LL p = 998244353;

LL quick_pow(LL a, LL b) {
   LL res = 1;
   while (b) {
      if (b&1) res = (res*a)%p;
      b>>=1;
      a = (a*a)%p;
   }
   return res;
}

LL C(LL n , LL m) {
     if (n<m) return 0;
     LL ans = 1;
     for (LL i=1; i<=m; i++) ans = ans*i%p;
     ans = quick_pow(ans,p-2);
     for (LL i=n; i>n-m; i--) ans  = ans*i%p;
     return ans;
}

int main(){
    while (scanf("%lld%lld%lld",&n,&m,&l)==3) {
        printf("%lld\n",quick_pow(n-m,l)*C(n,m)%p);
    }
    return 0;
}


I-填空题

#include <cstdio>
using namespace std;
 
int main(){
    printf("ac\n");
    return 0;
}


J-强迫症的序列

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 100000+5;
int a[maxn];
int n;
int total,t;
 
int main(){
    int T;
    scanf("%d",&T);
    while (T--){
        scanf("%d",&n);
        for (int i=1; i<=n; i++) scanf("%d",&a[i]);
        total = 0;
        sort(a+1,a+n+1);
        int sum = 0;
        t = a[n]-a[1];
        total += a[n]-a[1];
        for (int i=1; i<n; i++) a[i]+=t, sum += a[i] - a[n];
        total += sum;
        printf("%d %d\n",total,a[1]+sum);
    }
    return 0;
}


K-密码

#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
 
const int maxn = 100000+10;
int n,len,start;
char s[maxn];
vector<char> G[maxn];
 
int main(){
    int T;
    scanf("%d",&T);
    while (T--){
        scanf("%d",&n);
        scanf("%s",s);
        len = strlen(s);
        for (int i=1; i<=n; i++) G[i].clear();
 
        if (n==1)  { printf("%s\n",s); continue; }
 
        bool dir = 1;
        int cnt = 1;
        for (int i=0; i<len; i++) {
            if (cnt<=n && dir==1)  {
                G[cnt].push_back(s[i]);
                cnt++;
                if (cnt>n) {cnt = n-1; dir=0;}
            }
            else if (cnt>=1 && dir==0) {
                G[cnt].push_back(s[i]);
                cnt--;
                if (cnt<1) {cnt = 2; dir = 1;}
            }
        }
        for (int i=1; i<=n; i++) {
            for (int j=0; j<G[i].size(); j++) printf("%c",G[i][j]);
        }
        printf("\n");
    }
    return 0;
}


L-用来作弊的药水

#include <cstdio>
#include <cmath>
using namespace std;
 
const double eps = 1e-3;
int x,y,a,b;
double p,q;
 
int main(){
    int T;
    scanf("%d",&T);
    while (T--) {
        scanf("%d%d%d%d",&x,&a,&y,&b);
        p = (double)a*log2(x);
        q = (double)b*log2(y);
        if (fabs(p-q)<eps) printf("Yes\n"); else printf("No\n");
    }
    return 0;
}


最后附上一张补完题目的图,这次比赛学到了不少东西吧,补完题也挺有成就感的。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值