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; }