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 }

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;
        }
    }
}

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 }

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 }

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 }

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 }

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 }

原文地址:https://www.cnblogs.com/MXang/p/9801631.html

时间: 2024-08-30 11:28:37

2017-2018 ACM-ICPC Latin American Regional Programming Contest GYM101889的相关文章

训练20191007 2017-2018 ACM-ICPC Latin American Regional Programming Contest

2017-2018 ACM-ICPC Latin American Regional Programming Contest 试题地址:http://codeforces.com/gym/101889 总体情况 总共通过7题CEFGHIJ.其中我完成HIJ三题.纯属被大佬带飞系列. 解题报告 H - Hard choice 签到题 #include <bits/stdc++.h> using namespace std; int a1,b1,c1,a2,b2,c2; int main() {

2017-2018 ACM-ICPC Latin American Regional Programming Contest Solution

A - Arranging tiles 留坑. B - Buggy ICPC 题意:给出一个字符串,然后有两条规则,如果打出一个辅音字母,直接接在原字符串后面,如果打出一个元音字母,那么接在原来的字符串后面之后再翻转整个字符串,在这两条规则之下,求有多少种打印给定字符串的方法 思路:如果第一个字符是辅音,那么答案为0 如果全是辅音或全是元音,那么答案为1 如果只有一个辅音,答案为len 否则是最中间两个元音中间的辅音字符个数+1 1 #include <bits/stdc++.h> 2 3 u

2017-2018 ACM-ICPC Latin American Regional Programming Contest

题面pdfhttps://codeforc.es/gym/101889/attachments/download/7471/statements-2017-latam-regional.pdf zyn感冒,两个人打.刚开始两题超迅速,40分钟后开始各种写不出,自闭.然后突然又开出两题. 4题全部1A,70名左右应该能稳个银. 说明卡题了可千万不能放弃!虽然可能简单题做不出来,过的多的题目做不出来,也不要放弃去开题. 以及周末这两场都说明一定要胆子大. B---Buggy ICPC[找规律] 题意

2019-2020 ACM-ICPC Latin American Regional Programming Contest L - Leverage MDT

#include<map> #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define LL long long const int N=1010; int val[N][N]; int res[N][N]; char c[N][N]; int n,m; bo

2019-2020 ACM-ICPC Latin American Regional Programming Contest I - Improve SPAM 树形dp?

#include<iostream> #include<cstring> #define int long long using namespace std; const int N=4010,mod=1e9+7; int a[N]; int e[N*N],ne[N*N],idx,h[N]; int st[N]; int ans; int ans1[N]; int read() { int res=0,ch,flag=0; if((ch=getchar())=='-') //判断正

2019-2020 ACM-ICPC Latin American Regional Programming Contest A- Algorithm Teaching 二分图

#include<bits/stdc++.h> #define f first #define s second using namespace std; typedef long long ll; const int N=300005; typedef pair<int,int> P; int n,tot,t,V; map<string,int> mp; map<vector<int>,int> mp2; vector<int> G

2018-2019 ICPC Northwestern European Regional Programming Contest (NWERC 2018)

J题队友犯了初始化的错,白给6发,本来能1A的 B: solver:lzh.czq 就是个拓扑排序 1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ff first 4 #define ss second 5 #define mp make_pair 6 typedef long long ll; 7 typedef pair<int, int> pii; 8 9 vector<int> g[400

极角排序——ICPC Latin American Regional Contests 2019 D

这题还是按角度进行极角排序简单点 /* 按亮度从大到小排序,从大的给小的连一条向量,极角排序后所有向量在两个象限内,那么可行,反之不可行 */ #include<bits/stdc++.h> using namespace std; #define N 1005 typedef double db; const db eps=1e-8; const db pi=acos(-1); int sign(db k){ if (k>eps) return 1; else if (k<-ep

2019-2020 ICPC Southwestern European Regional Programming Contest (SWERC 2019-2020)

J想到了卡特兰数,也想到要按最小值分割数组,丢给队友之后两个人都没做出来,傻了 题目链接:https://codeforces.com/gym/102501 B: solver:czq 1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define pb emplace_back 6 #define mp make_pair 7 #define eps 1e-8 8