zoukankan      html  css  js  c++  java
  • 【2019湖北省大学程序设计竞赛】网赛

    因为已经是大三老狗了,也是正在备考研究生中。。。所以只是申请了号自己打。(连群都不敢进)

    感觉今年的题目还算简单的。QAQ。毕竟自己还能做。。(很久没碰真*算法了其实)

    而且没有教练给的压力,打的格外开心。

    下面就按照我自己做题的顺序来写题解啦。(并不是标程)


    E

    题意:给你一串数字,对应的是输入法中九键的键盘。n个测试样例的字符串,让你判断可不可能通过这串数字输出。

    题解:还是比较简单的模拟。开了个map存对应的数字。然后每个测试字符串对应存一个对应的(数字)字符串,然后对比输入的数字。记得去除大小写和空格。。(我是钻了stl的空子我觉得)

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 map <char,char> mp;
     5 
     6 void init(){
     7     mp['a']='2';mp['b']='2';mp['c']='2';
     8     mp['d']='3';mp['e']='3';mp['f']='3';
     9     mp['g']='4';mp['h']='4';mp['i']='4';
    10     mp['j']='5';mp['k']='5';mp['l']='5';
    11     mp['m']='6';mp['n']='6';mp['o']='6';
    12     mp['p']='7';mp['q']='7';mp['r']='7';mp['s']='7';
    13     mp['t']='8';mp['u']='8';mp['v']='8';
    14     mp['w']='9';mp['x']='9';mp['y']='9';mp['z']='9';
    15 }
    16 
    17 void trim(string &s){
    18     int index = 0;
    19     if( !s.empty()){
    20         while( (index = s.find(' ',index)) != string::npos){
    21             s.erase(index,1);
    22         }
    23     }
    24 
    25 }
    26 int main(){
    27     init();
    28     int T;
    29     cin>>T;
    30     for(int t = 1; t <= T; t++){
    31         string s;
    32         cin>>s;
    33         int n;
    34         cin>>n;
    35         printf("Case #%d:
    ",t);
    36         string ss;
    37         getline(cin,ss);
    38         while(n--){
    39             getline(cin,ss);
    40             trim(ss);
    41             transform(ss.begin(),ss.end(),ss.begin(),::tolower);
    42             string res;
    43             for(int i = 0; i < ss.size();i++){
    44                 //cout<<mp[ss[i]]<<endl;
    45                 res += mp[ss[i]];
    46             }
    47             if(res == s)    cout<<"Maybe.."<<endl;
    48             else    cout<<"How could that be possible?"<<endl;
    49         }
    50 
    51     }
    52     return 0;
    53 }
    View Code

    B

    题意:一个喝醉的小仓鼠,沿着上右下左的顺序走,问你n次后离原点的距离的平方是多少。

    题解:也是个简单模拟。把原点当作(0,0),上下左右也就是对xy+-.(记得long long)。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 
     5 int main(){
     6     int T;
     7     cin>>T;
     8     for(int t = 1; t <= T; t++){
     9         int n;
    10         cin>>n;
    11         int x=0,y=0;
    12         int xx;
    13 
    14         for(int i = 0; i < n ;i++){
    15             cin>>xx;
    16             if(i%4 == 0) y += xx;    
    17             else if(i%4 == 1)    x += xx;
    18             else if(i%4 == 2)    y -= xx;
    19             else if(i%4 == 3)    x -= xx;
    20         }
    21         ll dis = x*x + y*y;
    22         printf("Case #%d:%I64d
    ",t,dis);
    23     }
    24 
    25     return 0;
    26 }
    View Code

    F

    题意:有n座山,给你n座山的高度,n-1条路。m次询问。u和v之间经过的山第k高是哪一座。

    题解:一个主席树+LCA的静态区间查询第k小的模板题。。板子上是第k大,所以要改一下变成第k小。

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 
      4 const int maxN = 1e5 + 7;
      5 
      6 int N, M, a[maxN], b[maxN], diff, root[maxN][20], deep[maxN], cnt, head[maxN];
      7 int order, tree[maxN], lson[maxN*20], rson[maxN*20], siz[maxN*20];
      8 
      9 struct Eddge{
     10     int nex, to;
     11     Eddge(int a=-1, int b=0):nex(a), to(b) {}
     12 }edge[maxN<<1];
     13 
     14 void addEddge(int u, int v){
     15     edge[cnt] = Eddge(head[u], v);
     16     head[u] = cnt++;
     17 }
     18 
     19 void dfs(int u, int pre, int depth){
     20     root[u][0] = pre;
     21     deep[u] = depth;
     22     for(int i=head[u]; i!=-1; i=edge[i].nex){
     23         int v = edge[i].to;
     24         if(v == pre) continue;
     25         dfs(v, u, depth + 1);
     26     }
     27 }
     28 
     29 void pre_LCA(){
     30     dfs(1, 0, 0);
     31     for(int j=0; (1<<(j+1))<N ; j++){
     32         for(int i=1; i<=N; i++){
     33             if(root[i][j] < 0) root[i][j+1] = -1;
     34             else root[i][j+1] = root[root[i][j]][j];
     35         }
     36     }
     37 }
     38 
     39 int get_LCA(int x, int y){
     40     if(deep[x] < deep[y]) swap(x, y);
     41     int det = deep[x] - deep[y];
     42     for(int i=0; (1<<i)<=det; i++) if( (det>>i) & 1 ) x = root[x][i];
     43     if(x == y) return x;
     44     for(int i = log2(1. * N); i>=0; i--){
     45         if(root[x][i] != root[y][i]){
     46             x = root[x][i];
     47             y = root[y][i];
     48         }
     49     }
     50     return root[x][0];
     51 }
     52 
     53 void build(int &k, int l, int r){
     54     k = ++order;
     55     siz[k] = 0;
     56     if(l == r) return;
     57     int mid = (l + r)>>1;
     58     build(lson[k], l, mid);
     59     build(rson[k], mid + 1, r);
     60 }
     61 
     62 void update(int old, int &now, int l, int r, int qx){
     63     now = ++order;
     64     lson[now] = lson[old]; rson[now] = rson[old];   siz[now] = siz[old] + 1;
     65     if(l == r) return;
     66     int mid = (l + r)>>1;
     67     if(qx <= mid) update(lson[old], lson[now], l, mid, qx);
     68     else update(rson[old], rson[now], mid + 1, r, qx);
     69 }
     70 
     71 int query(int i, int j, int l, int r, int k, int lca, int fsa){
     72     if(l == r) return l;
     73     int det = siz[lson[i]] + siz[lson[j]] - siz[lson[lca]] - siz[lson[fsa]];
     74     int mid = (l + r)>>1;
     75     if(k <= det) return query(lson[i], lson[j], l, mid, k, lson[lca], lson[fsa]);
     76     else return query(rson[i], rson[j], mid + 1, r, k - det, rson[lca], rson[fsa]);
     77 }
     78 
     79 void dfs_build(int u, int pre){
     80     int pos = (int)(lower_bound(b + 1, b + diff + 1, a[u]) - b);
     81     update(tree[pre], tree[u], 1, diff, pos);
     82     for(int i=head[u]; i!=-1; i=edge[i].nex){
     83         int v = edge[i].to;
     84         if(v == pre) continue;
     85         dfs_build(v, u);
     86     }
     87 }
     88 
     89 void init(){
     90     memset(head, -1, sizeof(head));
     91     cnt = order = 0;
     92     memset(root, -1, sizeof(root));
     93 }
     94 
     95 int main(){   
     96     int T;
     97     cin>>T;
     98     while(T--){
     99         scanf("%d%d", &N, &M);
    100         init();
    101         for(int i=1; i<=N; i++){
    102             scanf("%d", &a[i]);
    103             b[i] = a[i];
    104         }
    105 
    106         sort(b + 1, b + N + 1);
    107         diff = (int)(unique(b + 1, b + N + 1) - b - 1);
    108         for(int i=1; i<N; i++){
    109             int e1, e2; scanf("%d%d", &e1, &e2);
    110             addEddge(e1, e2);
    111             addEddge(e2, e1);
    112         }
    113         pre_LCA();
    114         build(tree[0], 1, diff);
    115         dfs_build(1, 0);
    116         for(int i=1; i<=M; i++){
    117             int l, r, op;    scanf("%d%d%d", &l, &r, &op);
    118             int lca = get_LCA(l, r);
    119             //第k大变成第k小
    120             op = deep[l] + deep[r] - 2 * deep[lca] - op + 2;
    121             if(op<=0) printf("-1
    ");
    122             else
    123                 printf("%d
    ", b[query(tree[l], tree[r], 1, diff, op, tree[lca], tree[root[lca][0]])]);
    124         }
    125     }
    126     return 0;
    127 }
    View Code

    D

    题意:蒲公英的种子最开始在点(0,0),没风的时候上走,有风的时候向右走。它要到(m,n)请问有多少种走法。

    题解:经典。组合数问题啊。QAQ我记得我区预赛卡死在组合数上了。公式:C(n+m-1,m) -  C(n+m-1,m-1)。记得取模。

    代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 const int maxn = 500005, MOD = 1e9 + 7;
     5 int F[maxn], Finv[maxn], inv[maxn];//F是阶乘,Finv是逆元的阶乘 
     6 void init(){
     7     inv[1] = 1;
     8     for(int i = 2; i < maxn; i ++){
     9         inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD;
    10     }
    11     F[0] = Finv[0] = 1;
    12     for(int i = 1; i < maxn; i ++){
    13         F[i] = F[i-1] * 1ll * i % MOD;
    14         Finv[i] = Finv[i-1] * 1ll * inv[i] % MOD;
    15     }
    16 }
    17 int comb(int n, int m){
    18     if(m < 0 || m > n) return 0;
    19     return F[n] * 1ll * Finv[n - m] % MOD * Finv[m] % MOD;
    20 }
    21 
    22 int main() {
    23     init();
    24     int n, m;
    25     int t;
    26     scanf("%d",&t);
    27     while (t--) {
    28         scanf("%d%d", &m, &n);
    29         printf("%d
    ", (comb(n + m - 1, m) - comb(n + m - 1, m - 1) + MOD) % MOD);
    30     }
    31     return 0;
    32 }
    View Code

    A(计算几何)和C(线段树)我一时没有想到什么好的办法。打算看了标程再补一下题。。QAQ。

  • 相关阅读:
    文章的上一页和下一页功能
    mysql的子查询in()操作及按指定顺序显示
    apache的配置详解
    mysql replace()用法
    js判断手机登陆用户
    mysql的常用函数
    mysql substring_index()查询某个字符中以某个分割符分割后的值
    mysql复制表数据,多表数据复制到一张表
    mysql数据去重复distinct、group by
    js获取站点根目录
  • 原文地址:https://www.cnblogs.com/Asumi/p/10667385.html
Copyright © 2011-2022 走看看