1. 程式人生 > >2017-2018 ACM-ICPC Latin American Regional Programming Contest

2017-2018 ACM-ICPC Latin American Regional Programming Contest

pdf 反轉 enc pin rac alt target 不同的 暴力

題面pdfhttps://codeforc.es/gym/101889/attachments/download/7471/statements-2017-latam-regional.pdf

zyn感冒,兩個人打。剛開始兩題超迅速,40分鐘後開始各種寫不出,自閉。然後突然又開出兩題。

4題全部1A,70名左右應該能穩個銀。

說明卡題了可千萬不能放棄!雖然可能簡單題做不出來,過的多的題目做不出來,也不要放棄去開題。

以及周末這兩場都說明一定要膽子大。

B---Buggy ICPC【找規律】

題意:

輸入一串字符串,當遇到元音的時候前面輸入的所有字符包括這個元音都反轉一下。現在給定最後的結果字符串,問有多少種輸入方法可以得到這個字符串。

思路:

czc去打了個表,然後我們瘋狂找規律。真的找到規律了

如果沒有元音,當然是1.如果有元音,但是第一個不是元音,一定是0

其他情況,答案就是中間兩個元音之間的輔音個數$+1$。

只有一個元音時默認後面還有一個元音結尾,答案就是字符串長度。

技術分享圖片
 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 const int maxn = 1e5 + 5;
 6 char t[maxn];
 7 vector<int>pos_of_vowel;
 8 char vowel[5] = {a, e, 
i, o, u}; 9 10 int main() 11 { 12 while(scanf("%s", t) != EOF){ 13 pos_of_vowel.clear(); 14 int len = strlen(t), cnt = 0; 15 for(int i = 0; i < len; i++){ 16 for(int j = 0; j < 5; j++){ 17 if(t[i] == vowel[j]){ 18 cnt++;
19 pos_of_vowel.push_back(i); 20 } 21 } 22 } 23 24 if(cnt == 0){ 25 printf("1\n"); 26 } 27 else{ 28 bool flag = false; 29 for(int i = 0; i < 5; i++){ 30 if(t[0] == vowel[i]){ 31 flag = true; 32 break; 33 } 34 } 35 if(!flag){ 36 printf("0\n"); 37 } 38 else{ 39 if(cnt == 1){ 40 printf("%d\n", len); 41 } 42 else{ 43 int id = (cnt + 1) / 2; 44 //cout<<id<<endl<<pos_of_vowel[id]<<endl<<pos_of_vowel[id - 1]<<endl; 45 int l = pos_of_vowel[id] - pos_of_vowel[id - 1]; 46 printf("%d\n", l); 47 } 48 49 } 50 } 51 } 52 return 0; 53 }
View Code

H---Hard Choice【水題】

題意:

【略】

思路:

【略】

技術分享圖片
 1 #include<iostream>
 2 //#include<bits/stdc++.h>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<cstdlib>
 6 #include<cstring>
 7 #include<algorithm>
 8 #include<queue>
 9 #include<vector>
10 #include<set>
11 #include<climits>
12 #include<map>
13 using namespace std;
14 typedef long long LL;
15 #define N 100010
16 #define pi 3.1415926535
17 #define inf 0x3f3f3f3f
18 
19 int a, b, c;
20 
21 int main()
22 {
23     while(scanf("%d%d%d", &a, &b, &c) != EOF){
24         int x, y, z;
25         scanf("%d%d%d", &x, &y, &z);
26         int ans = 0;
27         if(x > a){
28             ans += x - a;
29         }
30         if(y > b){
31             ans += y - b;
32         }
33         if(z > c){
34             ans += z - c;
35         }
36         printf("%d\n", ans);
37     }
38 }
View Code

C---Complete Naebbirac‘s sequence【暴力】

題意:

有$n$個$1$到$k$之間的數。可以進行一下三種操作一次(只能一次):1、刪去其中一個。2、添加一個$1$到$k$的數。3、將其中一個換成另一個$1$到$k$的數。使得他們出現的次數都一樣。

思路:

因為只能操作一次。所以每種操作都討論一下就行了。

首先統計一下每個數出現的次數,按照次數從小到大排序。

1、把第一個數次數加1,看所有數是否滿足次數相同。

2、把最後一個數次數減1,看所有數是否滿足次數相同。

3、把第一個數次數加1,最後一個數次數減1,看所有數是否滿足次數相同。

技術分享圖片
 1 #include<iostream>
 2 //#include<bits/stdc++.h>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<cstdlib>
 6 #include<cstring>
 7 #include<algorithm>
 8 #include<queue>
 9 #include<vector>
10 #include<set>
11 #include<climits>
12 #include<map>
13 using namespace std;
14 typedef long long LL;
15 #define N 100010
16 #define pi 3.1415926535
17 #define inf 0x3f3f3f3f
18 
19 int n, k;
20 const int maxn = 1e4 + 5;
21 int num[maxn];
22 struct node{
23     int num, cnt;
24 }se[1005];
25 
26 bool cmp(node a, node b)
27 {
28     return a.cnt < b.cnt;
29 }
30 
31 int main()
32 {
33     while(scanf("%d%d", &k, &n) != EOF){
34         for(int i = 0; i < 1005; i++){
35             se[i].num = i;
36             se[i].cnt = 0;
37         }
38         for(int i = 0; i < n; i++){
39             scanf("%d", &num[i]);
40             se[num[i]].cnt++;
41         }
42 
43         sort(se + 1, se + k + 1, cmp);
44         bool flag = true;
45         se[1].cnt++;
46         for(int i = 1; i <= k-1; i++){
47             if(se[i].cnt != se[i + 1].cnt){
48                 flag = false;
49                 break;
50             }
51         }
52         if(flag){
53             printf("+%d\n", se[1].num);
54         }
55         else{
56             se[k].cnt--;
57             bool flag2 = true;
58             for(int i = 1; i <= k - 1; i++){
59                 if(se[i].cnt != se[i + 1].cnt){
60                     flag2 = false;
61                     break;
62                 }
63             }
64             if(flag2){
65                 printf("-%d +%d\n", se[k].num, se[1].num);
66             }
67             else{
68                 se[1].cnt--;
69                 bool flag3 = true;
70                 for(int i = 1; i <= k - 1; i++){
71                     if(se[i].cnt != se[i + 1].cnt){
72                         flag3 = false;
73                         break;
74                     }
75                 }
76                 if(flag3){
77                     printf("-%d\n", se[k].num);
78                 }
79                 else{
80                     printf("*\n");
81                 }
82             }
83         }
84     }
85 }
View Code

J---Jumping Frog【數論】【環形dp】

題意:

有n個位子,有的是石頭(R), 有的是池塘(P)。青蛙只能在石頭上跳,不能跳到池塘裏去。每次他選擇一個k,表示他每次跳k步,希望他可以跳回到起點。問以所有的位子為起點,一共能有多少種不同的k的選擇。

思路:

這題是真的沒思路。czc自己刷刷刷就敲完1A了。附一下他的代碼。

技術分享圖片
 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 const int MAX_N = 1e5 + 5;
 5 
 6 int N;
 7 char S[MAX_N];
 8 
 9 vector <int> factor;
10 void getFactors(int N)
11 {
12     factor.clear();
13     for (int i = 1; i <= N/i; i++) {
14         if (N%i == 0) {
15             factor.push_back(i);
16             if (i*i != N)
17                 factor.push_back(N/i);
18         }
19     }
20     sort(factor.begin(), factor.end());
21 }
22 
23 bool f[MAX_N << 1][50];
24 bool can_jump[MAX_N];
25 void dp()
26 {
27     int cnt = factor.size();
28     memset(f, false, sizeof f);
29     for (int i = 1; i <= 2*N; i++) {
30         for (int j = 0; j < cnt; j++) {
31             int tmp = factor[j];
32             if (S[(i-1)%N] == P)
33                 f[i][j] = false;
34             else if (S[(i-1)%N] == R) {
35                 if (i-tmp <= 0)
36                     f[i][j] = true;
37                 else
38                     f[i][j] = f[i-tmp][j];
39             }
40         }
41     }
42 
43     memset(can_jump, false, sizeof can_jump);
44     for (int i = N+1; i <= 2*N; i++) {
45         for (int j = 0; j < cnt; j++) {
46             int tmp = factor[j];
47             if (f[i][j])
48                 can_jump[tmp] = true;
49         }
50     }
51 }
52 
53 inline int gcd(int a, int b)
54 {
55     return a%b ? gcd(b, a%b) : b;
56 }
57 
58 int main()
59 {
60     scanf("%s", S);
61     N = strlen(S);
62     getFactors(N);
63     dp();
64 
65     int ans = 0;
66     for (int k = 1; k <= N-1; k++) {
67         int g = gcd(k, N);
68         if (can_jump[g])
69             ans++;
70     }
71     cout << ans << endl;
72     return 0;
73 }
View Code

2017-2018 ACM-ICPC Latin American Regional Programming Contest