A. Wrong Subtraction
題意:給出一個數字n,然後進行k次操作,每次在n的個位上減1,如果個位是0的話,去掉這一位,繼續操作,輸出最後結果思路:模擬減1操作,直接用個位數字與k比較,如果n大,那麼輸出n-k,否則需要判斷是否能把個位去掉
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
int main() {
ll n, k;
int ans = -1;
scanf("%lld %lld", &n, &k);
while(k > 0) {
int x = n % 10;
if(x > k) {
ans = n - k;
k = 0;
}else {
if(x == k) {
ans = n - x;
k = 0;
}else {
k = k - x - 1;
n /= 10;
ans = n;
}
}
}
printf("%d\n", ans);
return 0;
}
B. Two-gram
題意:給出一字符串,找出其中出現最多的兩個相鄰的字母思路:用string枚舉所有的可能,循環判斷次數
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
map<string, int> mp;
int main() {
int n, maxx = -1;
cin >> n;
string s, ans, p;
cin >> s;
for(int i = 0; i < n-1; i++) {
p = s.substr(i,2);
mp[p]++;
if(mp[p] > maxx) {
maxx = mp[p];
ans = p;
}
}
cout << ans << endl;
return 0;
}
C. Less or Equal
題意:給出n,k和一組數字(無大小順序),從n個數中找出k個數字,輸出一個x,x是大於等於k個數字中最大的,如果沒有輸出-1思路:首先排序,因爲要找k個數字,查看第k個數字是否跟k+1一樣大,如果一樣大就找不出k個(至少k+1個)
還有一個問題,當k爲0的情況,因爲$1<=a_{i}<=10^{9}$是從1開始的,當k=0時,要找出0個,如果排完續後$a_{1}=1的話,就不可能找出x,輸出-1
否則輸出1
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
const ll maxn = 1e6+5;
ll a[maxn];
int main() {
int n, m;
scanf("%d %d", &n, &m);
for(int i = 0; i < n; i++) {
scanf("%I64d", &a[i]);
}
sort(a,a+n);
if(n == m) {
printf("%I64d", a[m-1]);
return 0;
}
if(m == 0) {
if(a[0] == 1) printf("-1\n");
else printf("1\n");
}else {
if(a[m] == a[m-1]) printf("-1\n");
else printf("%I64d\n", a[m-1]);
}
return 0;
}
D. Divide by three, multiply by two
題意:給出一組數字,按照要求排序,規則是後面的數只能由前面的數÷3或者×2得來,題目一定可解思路:根據一個排序規則排序即可,根據每個數字對3能取餘的次數,從大到小排序,如果一樣的話,再根據剩下數字的從小到大排序 原因:要把能把3除盡的大的數字儘可能放前面,使他們變小,除了能÷3的數字,就是偶數,需要從小到大排,因爲×會變大
#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
#define INIT ios::sync_with_stdio(false)
using namespace std;
typedef long long ll;
const int maxn = 105;
ll a[maxn];
vector<ll> v;
bool cmp(ll a, ll b) {
int numa = 0, numb = 0;
while (a % 3 == 0) {
a /= 3;
numa++;
}
while (b % 3 == 0) {
b /= 3;
numb++;
}
if (numb != numa) return numa > numb;
return a < b;
}
int main() {
INIT;
int n;
ll x;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> x;
v.push_back(x);
}
sort(v.begin(), v.end(), cmp);
for (int i = 0; i < n - 1; i++) {
cout << v[i] << " ";
}
cout << v[n - 1] << endl;
return 0;
}
E. Cyclic Components
題意:給出一個圖,找出圖中有多少個環,都是單環,沒有多餘的邊思路:利用鏈表存儲,存儲兩個方向,根據一個點開始搜索,變搜索邊標記,如果每一個點可以連接另外兩個點(一個進一個出),那麼是符合要求的,如果不是,要麼不是環,要麼是一個複雜環
#include<iostream>
#include<algorithm>
#include<cstring>
#include <map>
using namespace std;
const int maxn = 2e5+10;
vector <int> v[maxn];
bool vis[maxn];
int flag;
void dfs(int x) {
vis[x] = true;
if(v[x].size() != 2) flag = 1;
for(int i : v[x]) {
if(!vis[i])
dfs(i);
}
}
int main() {
int n, m, ans = 0;
cin >> n >> m;
for(int i = 1; i <= m; i++) {
int x, y;
cin >> x >> y;
v[x].push_back(y);
v[y].push_back(x);
}
memset(vis, false, sizeof(vis));
for(int i = 1; i <= n; i++) {
flag = 0;
if(!vis[i]) {
dfs(i);
if(!flag) ans++;
}
}
cout << ans << endl;
return 0;
}
F. Consecutive Subsequence
題意:給出一組數字,輸出其中一組數的座標,要求是找出最長的上升序列,每次遞增1思路:用map記錄一個數字前面連續數字的個數,中間記錄最長的長度,和座標,最後根據最後的數字跟長度可以推算出開始的數字,循環輸出即可
#include<iostream>
#include<algorithm>
#include<cstring>
#include <map>
using namespace std;
typedef long long ll;
const int maxn = 2e5+10;
int a[maxn];
map<int ,int > mp;
int main() {
int n, ans, len = -1;
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> a[i];
int x = a[i];
mp[x] = mp[x-1] + 1;
if(len < mp[x]) {
len = mp[x];
ans = x;
}
}
cout << len << endl;
int startNum = ans - len + 1;
for(int i = 1; i <= n; i++) {
if(a[i] == startNum) {
cout << i << " ";
startNum++;
}
}
cout << endl;
return 0;
}