Codeforces Round #624 (Div. 3)简单题解分析
昨天因为一些事情,没有打cf,今天把题目补了一下,顺便整理一下题目,以供自己日后翻看。
废话不多说
对于A题
A. Add Odd or Subtract Even
就是一个简单大水题,让你计算由a转换到b的最小操作次数,对于a来说,每次操作可以加一个任意奇数,或者减去任意偶数
这个题只需简单判断一下a和b的大小关系,和奇偶关系,就可以算出操作次数,对于任意情况,操作数不会大于2

1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <algorithm> 5 #include <vector> 6 #include <map> 7 8 using namespace std; 9 10 typedef long long ll; 11 const int N = 1e6+10; 12 13 int main() 14 { 15 int t; 16 cin >> t; 17 while(t--) 18 { 19 ll a , b , p; 20 cin >> a >> b; 21 if(a==b) 22 { 23 cout << 0<<endl; 24 continue; 25 } 26 else if(a>b) 27 { 28 p = a - b; 29 if(p%2==0) 30 { 31 cout << 1<<endl; 32 } 33 else{ 34 cout << 2<<endl; 35 } 36 } 37 else if(a<b){ 38 p = b - a; 39 if(p%2==1) 40 { 41 cout << 1<<endl; 42 } 43 else{ 44 cout << 2<<endl; 45 } 46 } 47 } 48 return 0; 49 }
对于题目B. WeirdSort
我刚刚读完题目的时候是没有思路的,觉得自己很有可能就要卡在这道题上了,想了好久,不管怎么想都觉得有点问题,我就先去开了C题,写完c之后回来看这个题,发现数据量水的一批,完全可以暴力做啊,qwq
总共有n个数,我就排n遍,每次我都从第一个点开始往后更新,当我暴力完一遍后如果还不是非严格上升的话就是不可以了

1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <algorithm> 6 #include <stack> 7 using namespace std; 8 typedef long long ll; 9 const int N = 1e6+10; 10 stack<int>st; 11 int main() 12 { 13 int t; 14 cin >> t; 15 while(t--) 16 { 17 int n,m; 18 cin >> n >> m ; 19 int a[110],p[110]={0}; 20 for(int i = 1 ; i <= n ; i++) 21 { 22 scanf("%d",&a[i]); 23 } 24 for(int i = 0 ; i < m ; i++) 25 { 26 int q; 27 scanf("%d",&q);p[q]=1; 28 } 29 for(int i=1;i<=n;i++) 30 { 31 for(int j = 1;j<n;j++) 32 { 33 if(p[j]==1&&a[j]>a[j+1]) 34 { 35 //cout << " p: "<<p[j]<<" j: "<<j<<endl; 36 int t = a[j]; 37 a[j] = a[j+1]; 38 a[j+1]=t; 39 } 40 } 41 } 42 int flag=0; 43 for(int i=1;i<n;i++) 44 { 45 //cout<< a[i]<<" "; 46 if(a[i]>a[i+1]) 47 { 48 flag =1; 49 } 50 } 51 // cout << endl; 52 if(flag) 53 { 54 puts("NO"); 55 } 56 else{ 57 puts("YES"); 58 } 59 } 60 return 0; 61 }
对于题目C. Perform the Combo
这就是一个老生常谈的类型了,就是一个简单求前缀和的题目,我们只需要开一个vector<int>q[26],存下每一个字母的所有下标位置,然后在下面每个前缀字符串提取时用二分计算一下前缀和可以了,qwq,第一次就直接暴力交了一波,结果TLE了,这告诉我啊还是不要偷懒,尽量能优化就优化

1 #include<iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <map> 7 #include <stack> 8 9 using namespace std; 10 typedef long long ll; 11 const int N = 2e5+10; 12 vector<int>q[26]; 13 int p[N][26]; 14 int a[N]; 15 int ans[26]; 16 int main() 17 { 18 int t; 19 cin >> t; 20 while(t--) 21 { 22 int n,m; 23 memset(ans,0,sizeof(ans)); 24 string s; 25 cin >>n >> m; 26 cin >> s; 27 int len = s.size(); 28 for(int i=0;i<len;i++) 29 { 30 q[s[i]-'a'].push_back(i+1); 31 } 32 for(int i=0;i<m;i++) 33 { 34 scanf("%d",&a[i]); 35 for(int j =0;j<26;j++) 36 { 37 //int num =0; 38 int k = upper_bound(q[j].begin(),q[j].end(),a[i]) - q[j].begin(); 39 ans[j]+=k; 40 } 41 } 42 for(int i=0;i<26;i++)ans[i]+=q[i].size(); 43 for(int i=0;i<26;i++) 44 { 45 cout << ans[i]<<(i==25?'\n':' '); 46 q[i].clear(); 47 } 48 49 } 50 return 0; 51 }
对于D. Three Integers
又是一个爆炸性的大水题,题目意思是给我们三个整数a,b,c,要求我们用最小操作数,将a,b,c变成a|b,b|c,当时自己的第一想法竟然是去枚举分析a,b,c找一个变化最少的,结果想了半天也不知道怎么敲,后来忍不住去看了题解,原来可以暴力枚举,简直了,我太菜,果然是太菜限制了我的大脑
这个暴力枚举的时候也有一个小小的优化,就是a是每次加1,但对于b每次最少a,增加的必须是a的倍数,当然同样适应于c

1 //不该卡住了题目 2 //这个题也是比较坑的,可以直接暴力枚举,有一个小细节就是,枚举b的时候,b每次增加的都是a,而c每次增加的都是b 3 #include <iostream> 4 #include <cstdio> 5 #include <cstring> 6 #include <cmath> 7 #include <algorithm> 8 #include <map> 9 #include <vector> 10 #include <stack> 11 12 13 using namespace std; 14 typedef long long ll; 15 16 int main() 17 { 18 19 int t; 20 cin >> t; 21 while(t--) 22 { 23 int a,b,c; 24 cin >> a >> b >> c; 25 int aa,bb,cc; 26 ll m = 1e9+7; 27 for(int i=1;i<=20000;i++) 28 { 29 for(int j = i;j<=20000;j+=i) 30 { 31 for(int k =j;k<=20000;k+=j) 32 { 33 ll mx = abs(a-i)+abs(b-j)+abs(c-k); 34 if(mx < m) 35 { 36 m = mx; 37 aa = i; 38 bb = j; 39 cc = k; 40 } 41 } 42 } 43 } 44 cout << m<<endl; 45 cout << aa<<" "<< bb<<' '<<cc<<endl; 46 } 47 return 0; 48 }
对于E题,有一点简单的想法,就是对于n个点有两种极限情况,一个是完全二叉树,也就是最小的情况,另一种就是一条链,也就是最大的时候
只要在这之间就可有很多方式,emmm,
最后呢我对于F题也有思路知道怎么去做,可惜啊,学艺不精,不怎么会数据结构,这个题应该是用树状数组,因为速度过大也要离散化一下速度,
这里只要当xi《 xj && vi > vj d(i,j) 就是0,也就是i和j可以相遇,只有当xi<xj && vi<=vj 的情况下 d(i,j) = xj - xi;用树状数组来维护区间和就可以了应该
等我把树状数组补了,再来把这道题目补上,qwq!