2013暑假集训B组训练赛第二场
2013-07-27 11:16
302 查看
Problem A | CodeForces 79A | Bus Game |
这题先预处理求出三种拿钱方式(0、1、2张100),然后由这三种方式两两组合成9种方式;
然后按照优先选择的规则定义一个小于号,排一下序就ok了。
之后就是逐一的按照排好的顺序取钱。
#include <stdio.h> #include <algorithm> using namespace std; struct Meth{ int hud, ten; void init(int hud, int ten){ this->hud = hud, this->ten = ten; } bool operator==(const class Meth &ans)const{ return hud==ans.hud&&ten==ans.ten; } }; //两种比较方式 bool cmpC(const struct Meth &ans1, const struct Meth &ans2){ return ans1.hud>ans2.hud; } bool cmpH(const struct Meth &ans1, const struct Meth &ans2){ return ans1.ten>ans2.ten; } struct Comb{ Meth ci, ha; int chud, cten; void init(Meth a, Meth b){ ci.init(a.hud, a.ten), ha.init(b.hud, b.ten); chud = ci.hud+ha.hud, cten = ci.ten+ha.ten; } bool operator<(const class Comb &ans)const{//按照规则定义小于号 return (cmpC(ci, ans.ci)||(ci==ans.ci&&cmpH(ha, ans.ha))); } }; Meth mat[3]; Comb comb[9];//综合的使用方式 int cnt, cnthud, cntten; void Prepare(){ for(int i = 0; i < 3; i++) mat[i].init(i, 22-i*10); cnt = 0; for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++) comb[cnt++].init(mat[i], mat[j]); sort(comb, comb+cnt); } int main(){ Prepare(); while(scanf("%d%d", &cnthud, &cntten) != EOF){ for(int i = 0; i < cnt; i++){ if(cnthud >= comb[i].chud && cntten >= comb[i].cten){ int a = cntten/comb[i].cten; //可能会使用0张100(comb[i].chud=0) if(comb[i].chud != 0) a = min(a, cnthud/comb[i].chud); cnthud -= a*comb[i].chud, cntten -= a*comb[i].cten; } } if(cnthud*100+cntten*10>=220 && cntten >= 2){ printf("Ciel\n"); }else{ printf("Hanako\n"); } } return 0; }
Problem B | CodeForces 192A | Funky Numbers |
然后每个询问,枚举第一个k(k+1)/2的数,然后二分查找是否存在匹配的一个数,也就是看预处理的数组里是否存在n-(k+(k+1)/2)这个数。
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
typedef long long LL;
int cnt, n;
LL num[45000];
LL up = 1000000000;
void prepare(){
cnt = 0;
for(LL i = 1; ;i++){
LL tmp = i*(i+1)/2;
if(tmp <= up) num[cnt++] = tmp;
else break;
}
}
int main(){
prepare();
while(scanf("%d", &n) != EOF){
bool flag = false;
for(int i = 0; num[i] < n; i++){
int id = lower_bound(num, num+cnt, n-num[i])-num;//查找一个和num[i]互补的那种数
if(num[id]==n-num[i]){
flag = true;
break;
}
}
printf("%s\n", flag ? "YES" : "NO");
}
return 0;
}
Problem C | CodeForces 329A | Purification |
若可行,肯定是是下面两种情况:
1.每一行都有一列可以放,放在每一行的这个列
2.每一列都有一行可以放,放在每一列的这个行
#include <stdio.h> #include <string.h> const int maxn = 100+10; char str[maxn]; int row[maxn], col[maxn], n, m; int main(){ while(scanf("%d%d", &n, &m) != EOF){ for(int i = 1; i <= n; i++){ memset(row, -1, sizeof(row));//该行全部都不能放 memset(col, -1, sizeof(col)); } for(int i = 1; i <= n ; i++){ scanf("%s", &str[1]); for(int j = 1; str[j]; j++){ if(str[j] == '.'){ row[i] = j, col[j] = i;//该行的j列放,该列的i行可放 } } } int failr = -1, failc = -1; for(int i = 1; i <= n; i++){ if(row[i]==-1)failr = i; if(col[i]==-1)failc = i; } if(failr!=-1&&failc!=-1){ printf("-1\n"); continue; } if(failr==-1){//每行都有一个列可放 for(int i = 1; i <= n; i++) printf("%d %d\n", i, row[i]); }else{//每列都有个行可放 for(int j = 1; j <= n; j++) printf("%d %d\n", col[j], j); } } return 0; }
Problem D | CodeForces 216B | Forming Teams |
于是如果我们把有矛盾的人都归为一个集合,关键就成了查找数量为奇数的环的个数了
利用并查集,只要两个人有矛盾关系就把他们归为一个集合。
当出现一个矛盾关系,如果这两个人之前就有矛盾则说明出现了环,判断若为奇数,肯定有一个人要坐板凳了。
#include <stdio.h> #include <vector> using namespace std; const int maxn = 100+10; int n, m, ans; int fa[maxn], num[maxn];//集合的数量 int Root(int cur){ if(fa[cur] != cur) fa[cur] = Root(fa[cur]); return fa[cur]; } int main(){ while(scanf("%d%d", &n, &m) != EOF){ for(int i = 1; i <= n; i++) fa[i] = i, num[i] = 1; int a, b; ans = 0; for(int i = 1; i <= m; i++){ scanf("%d%d", &a, &b); int r1 = Root(a), r2 = Root(b); if(r1 == r2 && (num[r1]%2==1))//ÕÒµ½Ææ»· ans++; else fa[r1] = r2, num[r2] += num[r1]; } if((n-ans)%2==1) ans++; printf("%d\n", ans); } return 0; }
Problem E | CodeForces 266B | Queue at the School |
#include <stdio.h> #include <string.h> const int maxn = 60; char str[2][maxn]; bool flag[maxn]; int n, t, now, pre; int main(){ while(scanf("%d%d", &n, &t) != EOF){ now = 0, pre = 1; scanf("%s", str[now]); for(int i = 0; i < t; i++){ now ^= 1, pre ^= 1; memset(flag, false, sizeof(flag));//要不要改 for(int j = 0; j < n-1; j++){ if(str[pre][j]=='B' && str[pre][j+1]=='G')//前面是男的后面是女的 flag[j] = flag[j+1] = true;//要改 } for(int j = 0; j < n; j++) if(flag[j]) str[now][j]=(str[pre][j]=='G' ? 'B' : 'G'); else str[now][j]=str[pre][j]; } str[now] =0; printf("%s\n", str[now]); } return 0; }
相关文章推荐
- 2013暑假集训B组训练赛第二场 - A Bus Game
- 2013暑假集训B组训练赛第二场 - E Queue at the School
- 2013暑假集训B组训练赛第二场 - B - Funky Numbers
- 2013暑假集训B组训练赛第二场 - C - Purification
- 2013暑假集训B组训练赛第一场
- 2013暑假集训 第二场个人赛总结
- 暑假集训——个人训练赛04——I题
- 2013暑假集训第一天总结。
- 2013 - ECJTU 暑期训练赛第二场-problem-A
- 2017.8.22暑假集训第二十三天(下午训练赛)
- CSU-ACM暑假集训基础组训练赛(2) B - Problem B
- 2013 - ECJTU 暑期训练赛第二场-problem-E
- 2013暑假集训 第一场个人赛总结
- CSU-ACM暑假集训基础组训练赛(5-1) C - Problem C
- 2013 - ECJTU 暑期训练赛第二场-problem-G
- CSU-ACM2014暑假集训基础组训练赛(1) 解题报告
- 2013 - ECJTU 暑期训练赛第二场-problem-H
- 2013暑假集训 第三场个人赛总结
- CSU-ACM暑假集训基础组训练赛(2) D - Problem D
- CSU-ACM暑假集训基础组训练赛(5-1) A - Problem A