zoukankan      html  css  js  c++  java
  • 2017-2018 ACM-ICPC Latin American Regional Programming Contest GYM101889

    挺有意思的一套题,题也没有啥毒瘤了,本来是队切的结果种种原因大家全挂机了。

    只补了百人题,一共7个,其他的暂时先不补了,,也不会嘛qwq

    H:签到

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int a[18],b[18];
     4 int main(){
     5     cin>>a[1]>>a[2]>>a[3]>>b[1]>>b[2]>>b[3];
     6     int ans = 0;
     7     for(int i=1;i<=3;i++)
     8         ans+=max(0,b[i]-a[i]);
     9     cout<<ans<<endl;
    10 }
    View Code

    C:按情况模拟一下,签到。当时队友因为这个题写炸了心态受到了影响然后我又不在((

    #include <bits/stdc++.h>
    using namespace std;
    int k,n;
    int a[100005];
    int num[100005];
    vector<int> vis[100005];
    int main(){
        ios::sync_with_stdio(false);
        cin>>k>>n;
        int cnt = 0;
        int tmp = 0;//那一个超出k的数
        for(int i=1;i<=n;i++){
            cin>>a[i];
            if(a[i]>k){
                cnt++;
                tmp = a[i];
            } else{
                num[a[i]]++;
            }
        }
        for(int i=1;i<=k;i++){
            vis[num[i]].push_back(i);
        }
        if(cnt>=2){
            cout<<"*"<<endl;
        } else if(cnt==1){
            if((n-1)%k==0&&vis[(n-1)/k].size()==k){
                cout<<-tmp<<endl;
            } else if(n%k==0&&vis[n/k-1].size()==1&&vis[n/k].size()==k-1){//
                cout<<-tmp<<' '<<"+"<<vis[n/k-1][0]<<endl;
            } else{
                cout<<"*"<<endl;
            }
        } else if(cnt==0){
            if((n+1)%k==0&&vis[(n+1)/k].size()==k-1&&vis[(n+1)/k-1].size()==1){
                cout<<"+"<<vis[(n+1)/k-1][0]<<endl;
            } else if((n-1)%k==0&&vis[(n-1)/k].size()==k-1&&vis[(n-1)/k+1].size()==1){
                cout<<-vis[(n-1)/k+1][0]<<endl;
            } else if(n%k==0&&vis[n/k].size()==k-2&&vis[n/k+1].size()==1&&vis[n/k-1].size()==1){
                cout<<-vis[n/k+1][0]<<' '<<"+"<<vis[n/k-1][0]<<endl;
            } else{
                cout<<"*"<<endl;
            }
        }
    }
    View Code

    B:签到题

    题意:给你目标字符串,你每次可以输入一个字符,输入字符为元音是会在当前串会在输入后反转,求方案数。

    样例三很明显了,两边的顺序是固定的,只考虑 中间 那一部分就好。特殊情况判一下

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 string s;
     4 bool yuanyin(char a){
     5     return a=='a'||a=='e'||a=='i'||a=='o'||a=='u';
     6 }
     7 int main(){
     8     ios::sync_with_stdio(false);
     9     cin>>s;
    10     int n = s.length();
    11     int odd = 0,even = 0;//我不会别的英语了
    12     for(int i=0;i<n;i++){
    13         if(yuanyin(s[i]))
    14             even++;
    15         else
    16             odd++;
    17     }
    18     if(even==n||odd==n){
    19         cout<<1<<endl;
    20     } else{
    21         if(!yuanyin(s[0])){
    22             cout<<0<<endl;
    23         } else{
    24             int tmp = 0;
    25             int i=0;
    26             for(;i<n;i++) {
    27                 if (yuanyin(s[i]))
    28                     tmp++;
    29                 if (tmp == (even + 1) / 2) {
    30                     break;
    31                 }
    32             }
    33             int j=i+1;
    34             for(;j<n;j++){
    35                 if(yuanyin(s[j]))
    36                     break;
    37             }
    38             cout<<j-i<<endl;
    39         }
    40     }
    41 }
    View Code

    E:搜索题,可以利用数位dp的思想,唔数位dp我之前写过一篇博客所以这道题有了思路之后还是挺简单的。

    题意:给你一个串和整数n,包含数字和'?','?'可以用任意数替代但不能含前导0,求能被n整除的最小串。

     1 #include <bits/stdc++.h>
     2 //为什么取余的运算优先级会比加减法高啊喂。。。
     3 using namespace std;
     4 int dp[1005][1005];
     5 string s;int n,l;
     6 bool flag = false;
     7 void dfs(int len,int mod,string ans){
     8     if(flag) return;
     9     if(len==l){
    10         if(mod==0){
    11             cout<<ans<<endl;
    12             flag = true;
    13         }
    14         return;
    15     }
    16     if(dp[len][mod]) return;
    17     if(s[len]=='?'){
    18         for(int i=0;i<=9;i++){
    19             if(flag) return;
    20             if(len==0&&i==0) continue;
    21             dfs(len+1,(i+(mod*10))%n,ans+char(i+'0'));
    22         }
    23     } else{
    24         if(flag) return;
    25         dfs(len+1,(s[len]-'0'+mod*10)%n,ans+s[len]);
    26     }
    27     dp[len][mod]=1;
    28 }
    29 int main(){
    30     ios::sync_with_stdio(false);
    31     cin>>s>>n;
    32     l=s.length();
    33     dfs(0,0,"");
    34     if(!flag)
    35         cout<<"*"<<endl;
    36 }
    View Code

    J:简单数学题,一个字符串,R代表能跳,P代表不能,青蛙可以从任何地方跳,求能跳回原点的步数n的方案数,n需要小于字符串长度。

    很明显的gcd,然后判断一下因数就可以。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int gcd(int x,int y){
     4     return y==0?x:gcd(y,x%y);
     5 }
     6 string s;
     7 bool vis[100005];
     8 int main(){
     9     ios::sync_with_stdio(false);
    10     cin>>s;
    11     int n = s.length();
    12     for(int l=1;l<n;l++){
    13         if(n%l==0){
    14             for(int i=0;i<l;i++){
    15                 //如果在>=l的位置有解那么<l的位置一定也有解
    16                 int pos = i;
    17                 while (pos<n&&s[pos]=='R'){
    18                     pos+=l;
    19                 }
    20                 if(pos>=n){
    21                     vis[l]=true;
    22                 }
    23             }
    24         }
    25     }
    26     int ans = 0;
    27     for(int i=1;i<n;i++){
    28         if(vis[gcd(i,n)])
    29             ans++;
    30     }
    31     cout<<ans<<endl;
    32 }
    View Code

    I:次小生成树板子题,题意不说了很简单。很久没写过LCA的题了今天算是复习了一下。

    对于给定的那条边,如果本来就在MST里,直接输出,如果不在,减去两点间的最长路径即可,最长路径和LCA的数组一起处理就可以。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int N = 1e5+5;
      4 
      5 map<pair<int,int>,int>mt;
      6 
      7 int fa[N],ran[N];
      8 int find(int a){
      9     if(a==fa[a])return a;
     10     return fa[a]=find(fa[a]);
     11 }
     12 void unite(int x,int y){
     13     x = find(x);
     14     y = find(y);
     15     if(x==y) return;
     16     if(ran[x]<ran[y])fa[x]=y;
     17     else{
     18         fa[y]=x;
     19         if(ran[x]==ran[y])
     20             ran[x]++;
     21     }
     22 }
     23 bool same(int x,int y){
     24     return find(x)==find(y);
     25 }
     26 
     27 vector<int>g[N],val[N];
     28 int par[N][22],maxx[N][22],dep[N];
     29 void dfs(int v,int fa){
     30     for(int i=0;i<g[v].size();i++){
     31         int u = g[v][i];
     32         if(u==fa)
     33             continue;
     34         dep[u]=dep[v]+1;
     35         par[u][0]=v;
     36         maxx[u][0]=val[v][i];
     37         dfs(u,v);
     38     }
     39 }
     40 
     41 int lca_(int x,int y) {
     42     if (dep[x] > dep[y])
     43         swap(x, y);
     44     int tmp1 = mt[make_pair(x, y)];//
     45     int res = 0;
     46     for (int i = 20; i >= 0; i--){
     47         if (dep[y] - dep[x] >= (1 << i)) {
     48             res = max(res,maxx[y][i]);
     49             y = par[y][i];
     50         }
     51     }
     52     if(x==y)
     53         return tmp1-res;//多的长度
     54     //这两个一定在同一高度了
     55     for(int i=20;i>=0;i--) {
     56         if (par[x][i] == par[y][i])
     57             continue;
     58         else {
     59             res = max(res,maxx[x][i]);
     60             res = max(res,maxx[y][i]);
     61             x = par[x][i], y = par[y][i];
     62         }
     63     }
     64     res = max(res,maxx[x][0]);
     65     res = max(res,maxx[y][0]);
     66     return tmp1-res;
     67 }
     68 
     69 struct Edge{
     70     int from,to,cost;
     71     Edge(){}
     72     Edge(int from,int to,int cost):from(from),to(to),cost(cost){}
     73     bool operator <(const Edge &b)const {
     74         return cost<b.cost;
     75     }
     76 }edg[200005];
     77 
     78 int n,m,q,a,b,c;
     79 
     80 void init(){
     81     for(int j=1;(1<<j)<=n;j++){
     82         for(int i=1;i<=n;i++){
     83             par[i][j]=par[par[i][j-1]][j-1];
     84             maxx[i][j]=max(maxx[i][j-1],maxx[par[i][j-1]][j-1]);
     85         }
     86     }
     87 }
     88 
     89 int main(){
     90     ios::sync_with_stdio(false);
     91     for(int i=1;i<=100000;i++){
     92         fa[i]=i,ran[i]=0;
     93     }
     94     cin>>n>>m;
     95     for(int i=1;i<=m;i++){
     96         cin>>a>>b>>c;
     97         edg[i]=Edge(a,b,c);
     98         mt[make_pair(a,b)]=c;
     99         mt[make_pair(b,a)]=c;
    100     }
    101     sort(edg+1,edg+1+m);
    102     int ans = 0;
    103     for(int i=1;i<=m;i++){
    104         int u = edg[i].from,v = edg[i].to,cost = edg[i].cost;
    105         if(!same(u,v)){
    106             unite(u,v);
    107             ans+=cost;
    108             g[u].push_back(v);
    109             g[v].push_back(u);
    110             val[u].push_back(cost);
    111             val[v].push_back(cost);
    112         }
    113     }
    114     dep[1]=1;dfs(1,1);
    115     init();
    116     //cout<<ans<<endl;
    117     cin>>q;
    118     while (q--){
    119         cin>>a>>b;
    120         if(par[a][0]==b||par[b][0]==a)//本来就在MST里
    121             cout<<ans<<endl;
    122         else{
    123             cout<<ans+lca_(a,b)<<endl;
    124         }
    125     }
    126 }
    View Code

    F:离散化+树状数组。因为我是先学的线段树所以对树状数组不太熟。。。但还是能写下来的(((

    思路:两个值都相同的先合并,然后按一维排序,另一维做最大上升子序列权值和。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N = 100005;
     5 struct node{
     6     int a,b;
     7     ll cost;
     8 }p[N];
     9 int n,s[N*4];//离散化
    10 map<pair<int,int>, ll> m;
    11 vector<int> l[N*4];
    12 ll c[N*4];
    13 int lowbit(int k){ return k&-k;}
    14 void update(int pos,ll num){
    15     while (pos<=4*N){
    16         c[pos]=max(c[pos],num);
    17         pos+=lowbit(pos);
    18     }
    19 }
    20 ll maxx(int pos){
    21     ll s = 0;
    22     while (pos>0){
    23         s=max(s,c[pos]);
    24         pos-=lowbit(pos);
    25     }
    26     return s;
    27 }
    28 int cmp(int a,int b){
    29     return a>b;
    30 }
    31 int main(){
    32     ios::sync_with_stdio(false);
    33     cin>>n;
    34     for(int i=1;i<=n;i++){
    35         cin>>p[i].a>>p[i].b>>p[i].cost;
    36         s[2*i]=p[i].a;
    37         s[2*i-1]=p[i].b;
    38     }
    39     sort(s+1,s+2*n+1);
    40     int cnt = unique(s+1,s+2*n+1)-s-1;
    41     for(int i=1;i<=n;i++){
    42         int a = lower_bound(s+1,s+1+cnt,p[i].a)-s;
    43         int b = lower_bound(s+1,s+1+cnt,p[i].b)-s;
    44         m[make_pair(a,b)]+=p[i].cost;
    45         l[a].push_back(b);
    46     }
    47     for(int i=1;i<=cnt;i++){
    48         sort(l[i].begin(),l[i].end(),cmp);
    49         for(int j=0;j<l[i].size();j++){
    50             int b = l[i][j];
    51             ll tmp = maxx(b-1);
    52             ll all = tmp+m[make_pair(i,b)];
    53             update(b,all);
    54         }
    55     }
    56     cout<<maxx(cnt)<<endl;
    57 }
    View Code
  • 相关阅读:
    极具创意的专辑封面
    【Linux必知必会】五种开源协议的比较(BSD,Apache,GPL,LGPL,MIT)
    【Ubuntu技巧】Ubuntu下gedit 打开txt文件乱码的处理方法
    【Linux原理】Linux中硬链接和软链接的区别和联系
    【短语学习】out of the box的含义和翻译
    【Ubuntu技巧】在全新安装的Ubuntu上快速重装软件包
    【论文阅读心得】图像识别中一个常用词的中英文释义——artifact
    【短语学习】狮子那一份the lions share
    【OpenCV学习】摄像头显示、录像、拍照程序
    【Perl学习】学习笔记(持续更新中)
  • 原文地址:https://www.cnblogs.com/MXang/p/9801631.html
Copyright © 2011-2022 走看看