A. Wrong Subtraction
传送门:http://codeforces.com/contest/977/problem/A
题目大意:
给一个数,末尾为0时除以10,不为0时减1,输出k次操作后的结果。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#define P pair<int,int>
#define ll long long
#define INF 1e10
#define M 1e9+7
#define MAX 500010
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
using namespace std;
int n, k;
int main()
{
cin >> n >> k;
while (k--) {
if (n % 10 == 0)
n /= 10;
else
n--;
}
cout << n << endl;
return 0;
}
B. Two-gram
传送门:http://codeforces.com/contest/977/problem/B
题目大意:
给定一个字符串,输出该字符串中出现次数最多的长度为2的子串。
思路:
用map记录次数,遍历就好。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#define P pair<int,int>
#define ll long long
#define INF 1e10
#define M 1e9+7
#define MAX 500010
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
using namespace std;
int n;
string str;
map <string, int> mp;
int main()
{
cin >> n; getchar();
cin >> str;
for (int i = 0; i < n - 1; i++)
mp[str.substr(i,2)]++;
int maxx = -1;
string ans = "";
for (int i = 0; i < n - 1; i++) {
if (maxx < mp[str.substr(i, 2)]) {
maxx = mp[str.substr(i, 2)];
ans = str.substr(i, 2);
}
}
cout << ans << endl;
return 0;
}
C. Less or Equal
传送门:http://codeforces.com/contest/977/problem/C
题目大意:
给出n个数字,求x,使正好有k个数字小于等于x。
思路:
先排序,设最小的数字为a。
若k=0,如果a为1,则输出-1,否则输出a-1。
若k=n,直接输出10^9。
否则,判断第k个数和第k+1个数是否相等,相等输出-1,不相等输出第k个数。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#define P pair<int,int>
#define ll long long
#define INF 1e10
#define M 1e9+7
#define MAX 500010
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
using namespace std;
int a[200010];
int n, k;
int main()
{
cin >> n >> k;
for (int i = 0; i < n; i++)
cin >> a[i];
sort(a, a + n);
if (k == n) {
cout << 1000000000 << endl;
return 0;
}
else if (k == 0) {
if (a[0] == 1)
cout << -1 << endl;
else
cout << a[0] - 1 << endl;
return 0;
}
if (a[k - 1] == a[k])
cout << -1 << endl;
else
cout << a[k - 1] << endl;
return 0;
}
D. Divide by three, multiply by two
传送门:http://codeforces.com/contest/977/problem/D
题目大意:
给定一个序列,将这个序列排序,使得对于每个数都是前一个数的2倍或1/3倍。
思路:
由于是*2和/3,所以所有数字都不一样,可以用map来记录每个数字对应的位置,由于最大也就100个数字,所以dfs对于每个数字都跑一遍就可以了。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#define P pair<int,int>
#define ll long long
#define INF 1e10
#define M 1e9+7
#define MAX 500010
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
using namespace std;
int n;
bool judge;
ll a[110];
ll ans[110];
map <ll, int> mp;
void dfs(int i,int cnt)
{
if (judge)
return;
ans[cnt] = a[i];
if (cnt == n ) {
judge = true;
return;
}
if (a[i] % 3 == 0 && mp[a[i] / 3] != 0)
dfs(mp[a[i] / 3], cnt + 1);
if (mp[a[i] * 2] != 0)
dfs(mp[a[i] * 2], cnt + 1);
}
int main()
{
judge = false;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
mp[a[i]] = i;
}
for (int i = 1; i <= n; i++) {
if (judge)break;
dfs(i, 1);
}
for (int i = 1; i <= n; i++)
cout << ans[i] << ' ';
cout << endl;
return 0;
}
E. Cyclic Components
传送门:http://codeforces.com/contest/977/problem/E
题目大意:
给n个点,m条边,问有多少个环,环内所涉及的点不与环外的任何点有边相连。
思路:
利用vector来记录边。
若一个顶点所连接的边的条数不为2,则肯定不是某个环中的点,设为访问过的点。
遍历没访问过的点作为起始点,并且将该起始点标记为访问过的点,根据相连的边到达下一个顶点,判断该顶点是否被访问过以及条数是否为2,若有一项不满足则说明从起始点到这个顶点的所涉及的所有点都不可能是某个环中的点,若都满足则设为访问过的点并继续找下一个顶点,直到找到起始点说明找到了一个环。
重复上面的动作直到所有点都访问过。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#define P pair<int,int>
#define ll long long
#define INF 1e10
#define M 1e9+7
#define MAX 500010
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
using namespace std;
int n, m, x, y;
vector<int> node[200010];
int used[200010];
int main()
{
int ans = 0;
cin >> n >> m;
while (m--) {
cin >> x >> y;
node[x].push_back(y);
node[y].push_back(x);
}
for (int i = 0; i < n; i++)
if (node[i].size() != 2)
used[i] = 1;
for (int i = 0; i < n; i++) {
if (used[i] == 0 && node[i].size() == 2) {
used[i] = 1;
int start = i;
int u = i;
int v = node[i][0];
while (v != start) {
if (used[v] == 1 || node[v].size() != 2) {
used[v] = 1;
break;
}
used[v] = 1;
if (node[v][0] == u) {
u = v;
v = node[v][1];
}
else {
u = v;
v = node[v][0];
}
}
if (v == start)
ans++;
}
}
cout << ans << endl;
return 0;
}
F. Consecutive Subsequence
传送门:http://codeforces.com/contest/977/problem/F
题目大意:
给一个数列,找出其中最长的公差为1的等差数列。
思路:
用一个map来记录以n结尾的等差数列的长度,其中mp[n]=mp[n-1]+1。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#define P pair<int,int>
#define ll long long
#define INF 1e10
#define M 1e9+7
#define MAX 500010
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
using namespace std;
int n;
int a[200010];
map<int, int> mp;
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
int maxx = -1;
int number = -1;
for (int i = 1; i <= n; i++) {
if (mp.find(a[i] - 1) == mp.end())
mp[a[i] - 1] = 0;
mp[a[i]] = mp[a[i] - 1] + 1;
if (maxx < mp[a[i]]) {
maxx = mp[a[i]];
number = a[i];
}
}
cout << maxx << endl;
stack <int> s;
for (int i = n ; i >= 1; i--) {
if (a[i] == number) {
number--;
s.push(i);
}
}
while (!s.empty()) {
cout << s.top() << " ";
s.pop();
}
cout << endl;
return 0;
}