1. 程式人生 > >【2019湖北省大學程序設計競賽】網賽

【2019湖北省大學程序設計競賽】網賽

get eve 通過 span 順序 swap efi ble 代碼

因為已經是大三老狗了,也是正在備考研究生中。。。所以只是申請了號自己打。(連群都不敢進)

感覺今年的題目還算簡單的。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:\n",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\n",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\n");
122             else
123                 printf("%d\n", 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\n", (comb(n + m - 1, m) - comb(n + m - 1, m - 1) + MOD) % MOD);
30     }
31     return 0;
32 }
View Code


A(計算幾何)和C(線段樹)我一時沒有想到什麽好的辦法。打算看了標程再補一下題。。QAQ。

【2019湖北省大學程序設計競賽】網賽