Codeforces Round #479 (Div. 3) 题解

Codeforce官方给的题解 传送门

A. Wrong Subtraction

交题的传送门:http://codeforces.com/contest/977/problem/A

题意:题意很简单,就是给你一个数,如果能够整除10就直接将该数缩小10倍;否则直接将这个数减一。问k此操作之后,这个数n变为多少?

题解:直接按照题意模拟即可QAQ

代码如下:

 1 //A
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4
 5 int main()
 6 {
 7     int i,j,m,n,k;
 8     cin>>m>>k;
 9     int flag=0;
10     while(k){
11         while(m%10==0){
12             m/=10;
13             k--;
14             if(k==0) {flag =1;break;}
15         }
16         if(!flag){m--;
17         k--;}
18     }
19     cout<<m<<endl;
20     //cin>>j;
21     return 0;
22 }

B. Two-gram

交题的传送门:http://codeforces.com/contest/977/problem/B

题意:这个题意就是:给你一个字符串,然后这个字符串中任意连续的两个字符组合成的字符串,在原字符串中出现最多次数的字符串给找出来。

题解:直接按照题意模拟,将所截的字符串用map存起来并计数,然后找到最大次数并且将字符串记录,打出来就好了QAQ

代码如下:

 1 //B
 2 #include <iostream>
 3 #include <map>
 4 using namespace std;
 5 map<string, int> mp;
 6 int main()
 7 {
 8     int i, j, m, n, k;
 9     string s, p, q;
10     cin >> m;
11     cin >> s;
12     int maxn = -1;
13     for (i = 0; i < m-1; i++)
14     {
15         q=s.substr(i,2);
16         //cout<<i<<q<<endl;
17         mp[q]++;
18         if (mp[q] > maxn)
19         {
20             maxn = mp[q];
21             p = q;
22         }
23     }
24     cout<<p<<endl;
25     //cin>>k;
26     return 0;
27 }

C. Less or Equal

交题的传送门:http://codeforces.com/contest/977/problem/C

题意:给一个整数序列,是否找到一个数x,找到k个数字<=x,找到输出x,不能输出-1。看第二组数据,要找到两个数字,排序后出现1,3,3,会出现三个数字小于等于3,所以不能找到。

一个坑点,k=0的时候需要分类讨论,如果发现最小的数字是1的话,不能输出0,因为要求输出1~1e9之间的数,否则输出a[0]-1就可以QAQ

题解:排序以后分类判断即可。注意k=0时分类讨论

代码如下:

 1 //C
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<string.h>
 5 #include<stdlib.h>
 6 #include<bits/stdc++.h>
 7 using namespace std;
 8 int a[200005];
 9 bool cmp(int x,int y)
10 {
11     return x<y;
12 }
13 int main()
14 {
15     int i,j,m,k,n;
16     cin>>n>>k;
17     for(i=0;i<n;i++){
18         cin>>a[i];
19     }
20
21     sort(a,a+n,cmp);
22     if(n==k){
23         cout<<a[k-1]<<endl;
24         return 0;
25     }
26     if(k==0){
27         if(a[0]==1){
28             puts("-1");
29         }
30         else{
31             puts("1");
32         }
33
34         return 0;
35     }
36     if(a[k]==a[k-1]){
37         puts("-1");
38         //cin>>i;
39         return 0;
40     }
41     cout<<a[k-1]<<endl;
42     //cin>>i;
43     return 0;
44 }

D. Divide by three, multiply by two

交题的传送门:http://codeforces.com/contest/977/problem/D

题意:将给出的序列按照题目要求输出。选取一个数,然后通过除以3或者乘以2得到下一个数,然后将这些数按这个顺序直接打出来即可QAQ,数据保证有解

题解:将所有可以除以3的数全部记录次数存到数组里,按照从大到小的顺序直接排,将这个原来的数与这个新数组对应,从而输出来所有的数组。

其实一开始我用DFS去写,发现写不出来,结束了看大神代码,恍然大悟了。还是自己太菜了QAQ

代码如下:

 1 //D
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 typedef long long LL;
 5 int count3(LL x)
 6 {
 7     int ret=0;
 8     while(x % 3 == 0)
 9     {
10         ret++;
11         x /= 3;
12     }
13     return ret;
14 }
15 int n;
16 vector<pair<int,LL>> v;
17 int main()
18 {
19     cin>>n;
20     v.resize(n);
21     for(int i=0; i<n; i++)
22     {
23         cin>>v[i].second;
24         v[i].first=-count3(v[i].second);
25         //cout<<v[i].first<<endl;
26     }
27     sort(v.begin(), v.end());
28     for(int i=0; i<n; i++)
29         printf("%lld%c", v[i].second, " \n"[i + 1 == n]);
30 }

还有两个dalao的骚操作,大家可以看下

 1 //D
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 const int N=100+10;
 5 typedef long long int ll;
 6 ll a[N],b[N];
 7 map<ll,ll>m;
 8 int main()
 9 {
10     int n;
11     scanf("%d",&n);
12     m.clear();
13     for(int i=1; i<=n; i++)
14     {
15         scanf("%lld",a+i);
16         m[a[i]]=1;
17     }
18     sort(a+1,a+1+n);
19     int l=100,r=100;
20     b[l]=a[1];
21     while(r-l<n-1)
22     {
23         //cout<<l<<‘ ‘<<r<<endl;
24         if(m[b[r]*2]==1)
25         {
26             m[b[r]*2]=0;
27             r++;
28             b[r]=b[r-1]*2;
29         }
30         else if(b[r]%3==0&&m[b[r]/3]==1)
31         {
32             m[b[r]/3]=0;
33             r++;
34             b[r]=b[r-1]/3;
35         }
36         else if(m[b[l]*3]==1)
37         {
38             m[b[l]*3]=0;
39             l--;
40             b[l]=b[l+1]*3;
41         }
42         else if(b[l]%2==0&&m[b[l]/2]==1)
43         {
44             m[b[l]/2]=0;
45             l--;
46             b[l]=b[l+1]/2;
47         }
48     }
49     for(int i=l; i<=r; i++)
50     {
51         printf("%lld ",b[i]);
52     }
53     return 0;
54 }

 1 //D
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 typedef long long ll;
 5 int highest_power(ll n,int k)   //k is 3 or 2
 6 {
 7     int count=0;
 8     while(n%k==0)
 9     {
10         count++;
11         n=n/k;
12     }
13     return(count);
14 }
15 bool ispresent(ll num,ll n,ll a[])
16 {
17     for(int i=0; i<n; i++)
18     {
19         if(a[i]==num)
20             return(1);
21     }
22     return(0);
23 }
24 int main()
25 {
26     ll n;
27     cin>>n;
28     ll a[n];
29     for(ll i=0; i<n; i++)cin>>a[i];
30     pair <int,int> start;
31     int index=-1;
32     start= {-999999,999999};
33     for(int i=0; i<n; i++)
34     {
35         int temp3=highest_power(a[i],3);
36         int temp2=highest_power(a[i],2);
37         //cout<<temp3<<" "<<temp2<<endl;
38         if((temp3>=start.first)&&(temp2<=start.second))
39         {
40             start= {temp3,temp2};
41             index=i;
42         }
43         //cout<<"start: "<<start.first<<" "<<start.second<<endl;
44     }
45     cout<<a[index]<<" ";
46     ll curr=a[index];
47     for(int i=2; i<=n; i++)
48     {
49         if(curr%3==0)
50         {
51             if(ispresent(curr/3,n,a))
52             {
53                 curr=curr/3;
54                 cout<<curr<<" ";
55             }
56             else
57             {
58                 curr=2*curr;
59                 cout<<curr<<" ";
60             }
61         }
62         else
63         {
64             curr=2*curr;
65             cout<<curr<<" ";
66         }
67     }
68 }

E. Cyclic Components

交题的传送门:http://codeforces.com/contest/977/problem/E

题意:给你一些点与点直接的连通情况,这个是无向图,算出这个图中有几个圈。注意:圈中所有的节点的度为2

题解:用并查集直接统计,若两个节点的父亲节点是同一个,那么增加一个圈。算出圈的个数QAQ

代码如下:

 1 //E
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4
 5 struct node
 6 {
 7     int u;
 8     int v;
 9 }e[200005];
10 int du[200005],coun;
11 int father[200005];
12
13 void init(int x)
14 {
15     memset(du,0,sizeof(du));
16     for(int i=1;i<=x;i++)
17     {
18         father[i]=i;
19     }
20 }
21 int Find(int x)
22 {
23     if(x==father[x]) return x;
24     return father[x]=Find(father[x]);
25 }
26
27 void Union(int x,int y)
28 {
29     int dx=Find(x);
30     int dy=Find(y);
31     if(dx==dy) coun++;
32     else father[dx]=dy;
33 }
34
35 int main()
36 {
37     int i,j,m,n,k,x,y;
38     cin>>m>>n;
39     init(m);
40     for(i=1;i<=n;i++)
41     {
42         cin>>e[i].u>>e[i].v;
43         du[e[i].u]++;
44         du[e[i].v]++;
45     }
46     coun=0;
47     for(i=1;i<=n;i++)
48     {
49         if(du[e[i].u]==2&&du[e[i].v]==2){
50             Union(e[i].u,e[i].v);
51         }
52     }
53     cout<<coun<<endl;
54     return 0;
55 }

还有位dalao写的,参考一下

 1 //E
 2 #include<iostream>
 3 #include<string.h>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<map>
 7 #include<string>
 8 #include<stdio.h>
 9 #include<vector>
10 #include<stack>
11 #include<set>
12 using namespace std;
13 #define INIT ios::sync_with_stdio(false)
14 #define LL long long int
15
16 struct node {
17     int id;
18     int count;
19 };
20 int dp[2 * 100005];
21 vector<int>mm[200005];
22 void init() {
23     for (int i = 0;i < 2 * 100005;i++) {
24         dp[i] = i;
25     }
26 }
27
28 int _find(int x) {
29     if (dp[x] != x) {
30         return dp[x] = _find(dp[x]);
31     }
32     return dp[x];
33 }
34
35 void _union(int  x, int y) {
36     int xx = _find(x);
37     int yy = _find(y);
38     if (xx < yy) {
39         dp[xx]= yy;
40     }
41     else {
42         dp[yy] = xx;
43     }
44 }
45
46 int main() {
47     int n, m;
48     map<int, int>mp;//存每个节点的度
49     while (cin >> n >> m)
50     {
51         mp.clear();
52         init();
53         int a, b;
54         int ans = 0;
55         for (int i = 0;i < m;i++) {
56             cin >> a >> b;
57             mp[a]++;
58             mp[b]++;
59             if (_find(a) != _find(b)) {
60                 _union(a, b);
61             }
62         }
63         //通过父节点把连通图存进一个vector数组
64         for (int i = 1;i <= n;i++) {
65             mm[_find(i)].push_back(i);
66         }
67         for (int i = 1;i <= n;i++) {
68             //连通图至少要有3个点
69             if (mm[i].size() > 2) {
70                 int flag = 1;
71                 for (int j = 0;j < mm[i].size()&&flag;j++) {
72                     //只要有一个度不为2就跳出
73                     if (mp[mm[i][j]] != 2) {
74                         flag = 0;
75                     }
76                 }
77                 if (flag)ans++;
78             }
79         }
80         cout << ans << endl;
81     }
82     return 0;
83 }

F. Consecutive Subsequence

交题的传送门:http://codeforces.com/contest/977/problem/F

题意:给出一个n和n个数的序列,然后让你找到满足两个数之间相差为1的存在的最长的序列,让你输出他们的下标。

题解:

跟最长递增子序列差不多,但是他的数据有给的还是挺大的,两种方法,离散化一下,或者map搞一下,map比较好写,所以直接map存一下。接着你只需要保存最长的序列最后一个数的位置和数就可以,那么怎么保存呢?

因为我们需要顺序的从这个序列里找,可以每次把进来的数标记由前面一个数 + 1得到,即可以得到到这个数为止的最长序列的长度。

比如 3 3 4 7 5 6 8

3 的时候 我们就以m【2】 + 1 得到这个m【3】,但是因为m【2】没出现过,所以直接就是1,然后下一个3也是如此,4的时候就由m【3】 + 1 ,所以m【4】 = 2,然后依次到8,就可以在m【8】的位置保存到从0到8中,最长的序列长度。

边赋值,边找到最大值的下标和数,然后找到以后,有个最大值,用最大值减去长度 + 1是不是就可以得到他的起始数字了,然后再遍历一遍序列,找每个数就可以了,输出下标。

由于这道题目不知道如何表达,参考了这位大佬的题解QAQ,(实际上就是自己太菜了555555555

参考了这位dalao的题解:https://blog.csdn.net/qq_38185591/article/details/80256487

代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int a[200005];
 4 int main()
 5 {
 6     int i,j,m,n,k,x;
 7     cin>>m;
 8     map<int,int> dp;
 9     vector<int> ve;
10     for(i=0;i<m;i++)
11     {
12         cin>>a[i];
13     }
14     int ans=0;
15     int last=0;
16     for(i=0;i<m;i++)
17     {
18         x=a[i];
19         dp[x]=dp[x-1]+1;
20         if(ans<dp[x]){
21             ans=dp[x];
22             last=x;
23         }
24     }
25     cout<<ans<<endl;
26     for(i=m-1;i>=0;i--){
27         if(a[i]==last){
28             ve.push_back(i+1);
29             last--;
30         }
31     }
32     reverse(ve.begin(),ve.end());
33     for(i=0;i<ve.size();i++){
34         if(i==ve.size()-1){cout<<ve[i]<<endl;break;}
35         cout<<ve[i]<<‘ ‘;
36     }
37     return 0;
38 }

原文地址:https://www.cnblogs.com/Fantastic-Code/p/9037055.html

时间: 2024-11-03 06:35:46

Codeforces Round #479 (Div. 3) 题解的相关文章

Codeforces Round #262 (Div. 2) 题解

A. Vasya and Socks time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Vasya has n pairs of socks. In the morning of each day Vasya has to put on a pair of socks before he goes to school. When

Codeforces Round #FF (Div. 2) 题解

比赛链接:http://codeforces.com/contest/447 A. DZY Loves Hash time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output DZY has a hash table with p buckets, numbered from 0 to p?-?1. He wants to insert n 

Codeforces Round #259 (Div. 2) 题解

A. Little Pony and Crystal Mine time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Twilight Sparkle once got a crystal from the Crystal Mine. A crystal of size n (n is odd; n?>?1) is an n?×?n 

Codeforces Round #177 (Div. 2) 题解

[前言]咦?现在怎么流行打CF了?于是当一帮大爷在执着的打div 1的时候,我偷偷的在刷div 2.至于怎么决定场次嘛,一般我报一个数字A,随便再拉一个人选一个数字B.然后开始做第A^B场.如果觉得机密性不高,来点取模吧.然后今天做的这场少有的AK了.(其实模拟赛只做完了4题,最后1题来不及打了) 等等,话说前面几题不用写题解了?算了,让我难得风光一下啦. [A] A. Polo the Penguin and Segments time limit per test 2 seconds mem

Codeforces Round #534 (Div. 2)题解

Codeforces Round #534 (Div. 2)题解 A. Splitting into digits 题目大意 将一个数字分成几部分,几部分求和既是原数,问如何分可以使得分出来的各个数之间的差值尽可能小 解题思路 将n分成n个1相加即可 AC代码 #include<cstring> #include<string> #include<iostream> #include<cstdio> using namespace std; int main

Codeforces Round #561 (Div. 2) 题解

Codeforces Round #561 (Div. 2) 题解 题目链接 A. Silent Classroom 水题. Code #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 105; int n; char s[N], t[N]; int main() { cin >> n; for(int i = 1; i <= n; i++) { scanf(&q

Codeforces Round #608 (Div. 2) 题解

目录 Codeforces Round #608 (Div. 2) 题解 前言 A. Suits 题意 做法 程序 B. Blocks 题意 做法 程序 C. Shawarma Tent 题意 做法 程序 D. Portals 题意 做法 程序 E. Common Number 题意 做法 程序 结束语 Codeforces Round #608 (Div. 2) 题解 前言 题目链接:仅仅只是为了方便以题目作为关键字能查找到我的题解而已(逃 Codeforces 1271A Codeforce

Codeforces Round #617 (Div. 3) 题解

目录 Codeforces Round #617 (Div. 3) 题解 前言 A. Array with Odd Sum 题意 做法 程序 B. Food Buying 题意 做法 程序 C. Yet Another Walking Robot 题意 做法 程序 D. Fight with Monsters 题意 做法 程序 E1. String Coloring (easy version) 题意 做法 程序 E2. String Coloring (hard version) 题意 做法

[Codeforces Round #617 (Div. 3)] 题解 A,B,C,D,E1,E2,F

[Codeforces Round #617 (Div. 3)] 题解 A,B,C,D,E1,E2,F 1296A - Array with Odd Sum 思路: 如果一开始数组的sum和是奇数,那么直接YES, 否则:如果存在一个奇数和一个偶数,答案为YES,否则为NO 代码: int n; int a[maxn]; int main() { //freopen("D:\\code\\text\\input.txt","r",stdin); //freopen(