NUC.2015.秋.隊內訓練賽-第一場
----解題報告
Problem A CodeForces 445A DZY Loves Chessboard
題意:
有一個n行,m列的棋盤,在棋盤上面放置黑("B")和白("W")間隔的棋子,另外棋盤某些地方有缺損,不能放置棋子,用"-“表示。
算法:
這裏我採用直接模擬的方式,類似於小學生練字用的字帖,我先生成一個標準的BWBW間隔的棋盤,然後用輸入的棋盤,直接對比,如果是"."則直接輸出,標準棋盤的B或者是W,否則輸出"-"
如圖:當我把後面一個圖直接放在第一個圖上面時,就是標準答案!
代碼:
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <iomanip> #include <string> #include <vector> #include <cstdio> #include <stack> #include <queue> #include <cmath> #include <list> #include <map> #include <set> #define ULL unsigned long long #define PI 3.1415926535 #define INF 0x3f3f3f3f #define LL long long #define eps 1e-8 using namespace std; const int maxn = 110; char maze[maxn][maxn]; char res[maxn][maxn]; void init() { for(int i = 0; i < maxn; ++i) for(int j = 0; j < maxn; ++j) if((i + j ) % 2 == 0) res[i][j] = 'B'; else res[i][j] = 'W'; } int main() { #ifdef LOCAL //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); #endif // LOCAL init(); //初始化標準棋盤 int n, m; while(cin >> n >> m) { for(int i = 0; i < n; ++i) for(int j = 0; j < m; ++j) cin >> maze[i][j]; for(int i = 0; i < n; ++i) { for(int j = 0; j < m; ++j) if(maze[i][j] == '.') cout << res[i][j]; else cout << '-'; cout << endl; } } return 0; }
Problem B CodeForces 445B DZY Loves Chemistry
題意:
給出n個化學元素,和m對反應關係,求把化學元素放入試管能得到的最大值,初始化爲1,每發生一次反應,乘以2。
算法:
這題目,其實就是求解並查集的大小,我們把所有的並查集確定好,求出他們的大小,然後乘在一起就好了!
代碼:
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <iomanip> #include <string> #include <vector> #include <cstdio> #include <stack> #include <queue> #include <cmath> #include <list> #include <map> #include <set> #define ULL unsigned long long #define PI 3.1415926535 #define INF 0x3f3f3f3f #define LL long long #define eps 1e-8 using namespace std; int fa[55]; int Find(int num) { if (fa[num] != num) fa[num] = Find(fa[num]); return fa[num]; } void Union(int u, int v) { int fau = Find(u); int fav = Find(v); if (fau == fav) return; fa[fau] = fav; } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); #endif // LOCAL int n, m; int fr, to; while(~scanf("%d%d", &n, &m)) { if (m == 0) printf("1\n"); else { for(int i = 0; i < 55; ++i) fa[i] = i; for(int i = 0; i < m;++i) { scanf("%d%d", &fr, &to); Union(fr, to); } int maxn = 0; map<int, int>m; //這裏我設置map數組來統計一下,以某個點爲父節點的元素個數 for(int i = 1; i <= n; ++i) m[Find(i)]++; //統計並查集個數 for(int i = 1; i <= n;++i) if (m[i] > 1) maxn += (m[i] - 1); //計算總元素 printf("%I64d\n", (LL)pow(2, maxn)); //利用公式計算結果 } } return 0; }
Problem D CodeForces 447A DZY Loves Hash
題意:
給出一張hash表,構建方式爲對輸入的元素求餘數。接着是從頭開始依次把hash值,對應的下角標插入bucket,如果發生下角標重合,輸出目前元素的序號,如果一直沒有發生覆蓋,輸出-1
樣例說明:
0 21 53 41 53這組對應的餘數就是0 1 3 1 3
所以當插入第4個元素41的時候,下角標爲1,出現覆蓋,所以輸出4
代碼:
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <iomanip> #include <string> #include <vector> #include <cstdio> #include <stack> #include <queue> #include <cmath> #include <list> #include <map> #include <set> #define ULL unsigned long long #define PI 3.1415926535 #define INF 0x3f3f3f3f #define LL long long #define eps 1e-8 using namespace std; const int maxn = 305; int num[maxn]; bool vis[maxn]; int main() { #ifdef LOCAL //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); #endif // LOCAL int p, n; int tmp; while(cin >> p >> n) { memset(vis, false, sizeof(vis)); for(int i = 0; i < n; ++i) { cin >> tmp; num[i] = tmp % p; //構建hash表 } int res = -1; for(int i = 0; i < n; ++i) { if (!vis[num[i]]) vis[num[i]] = true; //設置vis數組查看是否有覆蓋 else { res = i + 1; break; } } cout << res << endl; } return 0; }
Problem E CodeForces 447B DZY Loves Strings
題意:
在已知的字符串中插入指定個數的字符,使得最終的字符串的權值和最大。仔細想一想,其實,我只需要在26個小寫字母的權值裏面,找到最大的那個字母,始終在最後面插入,就能保證最大。因爲前面的字符,不管怎麼分佈,字母單個的權值不會大於我選擇的這個字母。
代碼:
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <iomanip> #include <string> #include <vector> #include <cstdio> #include <stack> #include <queue> #include <cmath> #include <list> #include <map> #include <set> #define ULL unsigned long long #define PI 3.1415926535 #define INF 0x3f3f3f3f #define LL long long #define eps 1e-8 using namespace std; int main() { #ifdef LOCAL //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); #endif // LOCAL string s; int k, tmp; int w[26]; while(cin >> s) { cin >> k; for(int i = 0; i < 26; ++i) { cin >> tmp; w[i]= tmp; } int maxn = w[0]; for(int i = 1; i < 26; ++i) maxn = max(maxn, w[i]); //找到最大權值 LL sum = 0; for(int i = 0; i < s.size(); ++i) sum += ((i + 1) * w[s[i] -'a']); //利用題目中的公式計算出原字符串的權值和 sum += maxn * ((s.size() + 1 + s.size() + k) * k / 2); //求解追加字符串的權值和 cout << sum << endl; } return 0; }
Problem F CodeForces 448A Rewards
題意:
一個人,有很多獎牌和獎盃,分別有1, 2, 3等獎,現在需要把他們放到類似於盒子的東西里,爲給定的盒子能不能放完。已知獎牌每個盒子最多放10個,獎盃最多放置5個。所以我們只需要先把所有的獎牌和獎盃分別加起來,然後計算一下即可!
代碼:
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <iomanip> #include <string> #include <vector> #include <cstdio> #include <stack> #include <queue> #include <cmath> #include <list> #include <map> #include <set> #define ULL unsigned long long #define PI 3.1415926535 #define INF 0x3f3f3f3f #define LL long long #define eps 1e-8 using namespace std; int main() { #ifdef LOCAL //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); #endif // LOCAL int a1,a2, a3; int b1, b2, b3; int n; while(cin >> a1 >> a2 >> a3 >> b1 >> b2 >> b3 >> n) { int a = a1 + a2 + a3; int b = b1 + b2 + b3; int sum = 0; if (a % 5 == 0) sum = a / 5; else sum = a / 5 + 1; if (b % 10 == 0) sum += b / 10; else sum += b / 10 + 1; if (sum <= n) cout << "YES" << endl; else cout << "NO" << endl; } return 0; }