题目链接

A - Who Is The Winner

模拟。

#include <bits/stdc++.h>
using namespace std; int T;
int n;
struct X {
string name;
int num;
int ti;
}s[10010]; bool cmp(X&a,X&b){
if(a.num != b.num) return a.num > b.num;
return a.ti < b.ti;
} int main() {
scanf("%d", &T);
while(T--) {
scanf("%d",&n);
for(int i=0;i<n;i++){
cin>>s[i].name;
cin>>s[i].num;
cin>>s[i].ti; // cout << i << endl;
} for(int i = 0; i < n; i ++) {
//cout << s[i].name << " " << s[i].num << " " << s[i].ti << endl;
}
sort(s, s+n, cmp);
cout << s[0].name<<endl;
}
return 0;
}
/*
2
3
tourist 13 567
petr 13 600
endagorion 144 19
2
tourist 7 512
bayashout ​7 477 */

B - Rock-Paper-Scissors

枚举 $x$ 和 $y$,确定z,然后区间和算一下就能算出来谁赢了。

#include <bits/stdc++.h>
using namespace std; int T;
int n;
char s[1010]; int sum[1010][3]; int Get(int L, int R, int num) {
if(R < L) return 0;
return sum[R][num] - sum[L-1][num];
} int check(int x, int y, int z) {
//[1,x] R
//[x+1,x+y] P
//[x+y+1,x+y+z] S int point1 = Get(1,x,1);
int pin1 = Get(1,x,0);
int point2 = Get(x+1,x+y,0);
int pin2 = Get(x+1,x+y,2);
int point3 = Get(x+y+1,x+y+z,2);
int pin3 = Get(x+y+1,x+y+z,1); // cout << point1 << " "<< point2 << " " << point3 << endl; int point_first = point1+point2+point3;
int point_second = n - point_first - pin1 - pin2-pin3; if(point_first > point_second) return 1;
return 0; } int main() {
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
scanf("%s", s);
memset(sum, 0, sizeof sum);
for(int i = 0; s[i]; i ++) {
sum[i+1][0] = sum[i][0];
sum[i+1][1] = sum[i][1];
sum[i+1][2] = sum[i][2];
if(s[i] == 'R') sum[i+1][0] ++;
if(s[i] == 'S') sum[i+1][1] ++;
if(s[i] == 'P') sum[i+1][2] ++;
} int ans = 0;
int len = strlen(s);
for(int x = 0; x <= len; x ++) {
for(int y = 0; y <= len; y ++) {
if(x + y > len) continue;
int z = len - x - y;
ans = ans + check(x, y, z);
}
}
printf("%d\n", ans);
}
return 0;
}

C - Street Lamps

先把照亮的都确定一下,然后看连续的没被照亮的有几个,算一下就好了。

#include <bits/stdc++.h>
using namespace std; int T,n;
char s[100010]; int cal(int x) {
if(x == 0) return 0;
int res = x / 3;
if(x % 3) res ++;
return res;
} int main() {
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
scanf("%s",s);
int ans = 0;
int len = strlen(s);
for(int i = 0; s[i]; i++) {
if(s[i] == '*') {
if(i - 1 >= 0 && s[i-1] == '.') s[i -1] = '0';
if(i + 1 < len && s[i+1] == '.') s[i+1] = '0';
}
} int num = 0;
for(int i = 0; s[i]; i ++) {
if(s[i] != '.') {
ans = ans + cal(num);
num = 0;
} else {
num ++;
}
}
ans = ans + cal(num);
printf("%d\n", ans);
}
return 0;
}

D - Alternating Strings

$dp_i$ 表示前缀需要分割成几段,枚举上一次断开的位置即可。

#include <bits/stdc++.h>
using namespace std; int T;
int n, k, len;
char s[1010];
int dp[1010];
int jiao[1010][1010]; int Get(int x) {
if(x == -1) return 0;
return dp[x];
} int main() {
scanf("%d", &T);
while(T--) {
memset(jiao,0,sizeof jiao);
scanf("%d%d",&n,&k);
scanf("%s",s);
len = strlen(s); for(int i = 0; i < len; i ++) {
if(i + 1 < len) {
if(s[i] != s[i + 1]) jiao[i][i + 1] = 1;
}
for(int j = i + 2; j < len; j ++) {
if(s[j] != s[j - 1] && jiao[i][j - 1]) jiao[i][j] = 1;
}
} for(int i = 0; i < n; i ++) {
for(int j = i; j < n; j ++) {
// cout << i << " " << j << " " << jiao[i][j] << endl;
}
} dp[0] = 1;
for(int i = 1; i < n; i ++) {
dp[i] = 100000;
for(int j = i - 1; j >= -1; j --) {
// [j+1, i]
if(i - j > k) continue;
if(jiao[j+1][i]) continue;
dp[i] = min(dp[i], Get(j) + 1);
}
} printf("%d\n", dp[len - 1] - 1);
}
return 0;
}

E - Epic Professor

模拟。

#include <bits/stdc++.h>
using namespace std; int T;
int n;
int x[100010]; int main() {
scanf("%d", &T);
while(T--) {
scanf("%d",&n);
int ans = 0;
int cha = 1000;
for(int i=0;i<n;i++){
cin>>x[i];
cha = min(cha, 100 - x[i]);
} for(int i = 0; i<n;i++) {
if(x[i] + cha >= 50) ans ++;
} cout << ans << endl;
}
return 0;
}

F - Travelling Salesman

克鲁斯卡尔执行过程中,最小生成树上最大的边权就是答案。

#include <bits/stdc++.h>
using namespace std; const int maxn = 1e5+10;
int T;
int n,m;
struct Edge {
int u, v;
int c;
}e[maxn]; int f[maxn]; int Find(int x) {
if(x != f[x]) f[x] = Find(f[x]);
return f[x];
} bool cmp(Edge&a,Edge&b){
return a.c<b.c;
} int main() {
scanf("%d", &T);
while(T--) {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)f[i]=i;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].c);
}
sort(e+1,e+1+m,cmp);
int ans = 0;
for(int i=1;i<=m;i++){
int fu=Find(e[i].u);
int fv=Find(e[i].v);
if(fu==fv)continue;
f[fu]=fv;
ans=e[i].c;
}
printf("%d\n",ans);
}
return 0;
} /*
2
6 7
1 2 3
2 3 3
3 1 5
3 4 4
4 5 4
4 6 3
6 5 5 3 3
1 2 1
2 3 2
3 1 3 */

G - Heavy Coins

状压一下,某个状态是否可行,只要看看扔掉任意一个,是否都是不可行的。

#include <bits/stdc++.h>
using namespace std; const int maxn = 1e5+10;
int T;
int n;
int s; int dp[1200];
int sum[1200]; int a[20]; int lowbit(int x) {
return x & (-x);
} int main() {
scanf("%d",&T);
while(T--) {
scanf("%d%d", &n, &s);
for(int i = 0; i < n; i ++) {
scanf("%d", &a[i]);
}
for(int i = 1; i < (1 << n); i ++) {
for(int j = 0; j < n; j ++) {
if((1 << j) & i) {
sum[i] = sum[i ^ (1 << j)] + a[j];
}
}
} int ans = 0;
for(int i = 1; i < (1 << n); i ++) {
if(sum[i] < s) continue; int ok = 1; for(int j = 0; j < n; j ++) {
if((1 << j) & i) {
if(sum[i ^ (1 << j)] >= s) ok = 0;
}
} if(ok == 0) continue;
int tmp = 0;
for(int j = 0; j < n; j++) {
if((1 << j) & i) tmp ++;
}
ans = max(ans, tmp);
}
printf("%d\n", ans);
}
return 0;
}

H - Bridges

求出割边,去掉割边,每个连通块缩点,会形成一棵树,看看树的直径,最优策略就是在直径两端添加边。

#include <bits/stdc++.h>
using namespace std; const int N = 2e5 + 10;
int dfn[N],low[N],dfs_clock; int n, m;
int h[N], to[N], nx[N], sz; int bridge[N]; int belong[N];
int block; int p1, p2;
int dis1, dis2;
int f[N]; vector<int> g[N]; void add(int a, int b) {
to[sz] = b;
nx[sz] = h[a];
h[a] = sz ++;
} void tarjan(int u, int fa)
{
dfn[u] = low[u] = ++dfs_clock;
bool flag = false;
for(int i=h[u]; i != -1; i = nx[i])
{
int v = to[i];
if(v==fa && !flag)//如果有重边,那么边(u,v)被存了两次,所以,如果第二次访问,就让他通过
{
flag = true;
continue;
}
if(dfn[v] == 0)
tarjan(v,u);
low[u] = min(low[u],low[v]);
if(low[v] > dfn[u]) {
//cntCut++;
bridge[i] = 1;
}
}
} void dfs(int x) {
belong[x] = block;
for(int i = h[x]; i != -1; i = nx[i]) {
if(bridge[i]) continue;
if(belong[to[i]]) continue;
dfs(to[i]);
}
} void dfs1(int x, int y) {
f[x] = 1;
if(y > dis1) {
dis1 = y;
p1 = x;
}
for(int i = 0; i < g[x].size(); i ++) {
if(f[g[x][i]]) continue;
dfs1(g[x][i], y + 1);
}
} void dfs2(int x, int y) {
f[x] = 1;
if(y > dis2) {
dis2 = y;
p2 = x;
}
for(int i = 0; i < g[x].size(); i ++) {
if(f[g[x][i]]) continue;
dfs2(g[x][i], y + 1);
}
} int main()
{
int T;
scanf("%d", &T);
while(T--) {
scanf("%d%d",&n,&m); sz = 0;
dfs_clock = 0;
memset(dfn, 0, sizeof dfn);
memset(low,0,sizeof low); for(int i = 0; i <= n; i ++) {
h[i] = -1;
}
for(int i=0; i<m; ++i)
{
int a, b;
scanf("%d%d",&a,&b);
add(a, b);
add(b, a);
} memset(bridge, 0, sizeof bridge);
tarjan(1, -1);
for(int i = 0; i < sz; i ++) {
if(bridge[i]) bridge[i ^ 1] = 1;
} /*
for(int from = 1; from <= n; from ++) {
for(int i = h[from]; i != - 1; i = nx[i]) {
if(bridge[i])
printf("%d - %d\n", from, to[i]);
}
}
*/ memset(belong,0,sizeof belong);
block = 0;
for(int i = 1; i <= n; i ++) {
if(belong[i] == 0) {
block ++;
dfs(i);
}
} /*
for(int i = 1; i <= n; i ++) {
cout << i << " " << belong[i] << endl;
}
*/ for(int i = 1; i <= block; i ++) {
g[i].clear();
} for(int from = 1; from <= n; from ++) {
for(int i = h[from]; i != - 1; i = nx[i]) {
if(bridge[i]) {
// cout << belong[from] << " " << belong[to[i]] << endl;
g[belong[from]].push_back(belong[to[i]]);
g[belong[to[i]]].push_back(belong[from]);
}
}
} memset(f,0,sizeof f);
p1 = 0;
dis1 = 0;
dfs1(1, 0); memset(f,0,sizeof f);
p2 = 0;
dis2 = 0;
dfs2(p1,0); printf("%d\n", block - 1 - dis2);
}
return 0;
}

I - Bahosain and Digits

枚举答案,以及枚举最终变到哪个数字,然后验证一下是否可行。

#include <bits/stdc++.h>
using namespace std; int T;
char s[500];
int f[500], t[500], ci[500], sum[500];
int len; int Get(int x) {
if(x < 0) return 0;
return sum[x];
} int Sum(int L, int R) {
return (Get(R) - Get(L - 1) + 10) % 10;
} bool check(int x, int y) {
for(int i = 0; i < len; i ++) {
t[i] = f[i];
ci[i] = 0;
sum[i] = 0;
}
for(int i = 0; i <= len - x; i ++) {
ci[i] = 0;
t[i] = (t[i] + Sum(i-x+1,i-1)) % 10;
while(t[i] != y) {
t[i] = (t[i] + 1) % 10;
ci[i] ++;
}
sum[i] = (Get(i - 1) + ci[i]) % 10;
}
for(int i = len - x + 1; i < len; i ++) {
ci[i] = 0;
t[i] = (t[i] + Sum(i-x+1,i-1)) % 10;
// cout << i << " " << i-x+1 << " " << i-1 << endl;
sum[i] = (Get(i - 1) + ci[i]) % 10;
} for(int i = 0; i< len; i++) {
if(t[i] != t[0]) return 0;
}
return 1;
} int main() {
scanf("%d", &T);
while (T--) {
scanf("%s", s);
len = strlen(s);
for(int i = 0; s[i]; i ++) {
f[i] = s[i] - '0';
} int ans = 1;
int ok = 0;
for(int i = len; i >= 1; i --) {
for(int limit = 0; limit <= 9; limit ++) {
if(check(i, limit)) {
ans = i;
ok = 1;
break;
}
}
if(ok) break;
}
printf("%d\n", ans);
}
return 0;
}

J - Candy

贪心。人按年龄排序,糖果按个数排序,贪心拿就好了。

#include <bits/stdc++.h>
using namespace std; int T;
int n, m; int age[100010];
int tang[100010]; struct X {
int x, y;
}s[100010], t[100010]; int sz1, sz2; int main() {
scanf("%d",&T);
while(T--) {
scanf("%d%d",&n, &m);
for(int i = 1; i <= n; i ++) {
scanf("%d", &age[i]);
}
sort(age + 1, age + 1 + n); for(int i = 1; i <= m; i ++) {
scanf("%d", &tang[i]);
}
sort(tang+1, tang+1+m); sz1 = 0, sz2 = 0; s[sz1].x = age[1];
s[sz1].y = 1;
for(int i =2 ; i <= n;i ++) {
if(age[i] != s[sz1].x) {
sz1 ++;
s[sz1].x = age[i];
s[sz1].y = 1;
} else {
s[sz1].y ++;
}
} for(int i = 0; i <= sz1; i ++){
// cout << s[i].x << " " << s[i].y << endl;
} t[sz2].x = tang[1];
t[sz2].y = 1;
for(int i = 2; i <= m; i ++) {
if(tang[i] != t[sz2].x) {
sz2 ++;
t[sz2].x = tang[i];
t[sz2].y = 1;
} else {
t[sz2].y ++;
}
} for(int i = 0; i <= sz2; i ++){
// cout << t[i].x << " " << t[i].y << endl;
} int ok = 1; int p2 = 0;
for(int i = 0; i <= sz1; i ++) {
while(p2 <= sz2 && t[p2].y < s[i].y) {
p2 ++;
}
if(p2 > sz2) {
ok = 0;
break;
}
p2 ++;
}
if(ok) printf("YES\n");
else printf("NO\n");
}
return 0;
}

K - Runtime Error

枚举一下就好了,注意 $a_i$ 为 $0$ 的情况。

#include <bits/stdc++.h>
using namespace std; const int maxn = 1e5 + 10;
int T;
int f[maxn];
int a[maxn]; int n,k; int main() {
scanf("%d", &T);
while(T--) {
memset(f, 0, sizeof f);
scanf("%d%d", &n, &k);
for(int i =1; i <= n; i ++) {
scanf("%d", &a[i]);
f[a[i]] ++;
} sort(a+1,a+1+n); int ok = 0;
for(int i =1 ; i <= n; i ++) {
if(a[i] == 0) continue;
if(k % a[i]) continue;
if(a[i] != k / a[i]) {
if(f[a[i]] && f[k / a[i]]) {
printf("%d %d\n", a[i], k / a[i]);
ok = 1;
break;
}
} else {
if(f[a[i]] >= 2) {
printf("%d %d\n", a[i], k / a[i]);
ok = 1;
break;
}
}
} if(ok == 0) printf("-1\n"); }
return 0;
}

L - Alternating Strings II

D题的加强版,可以发现能推到 $i$ 位置的是一段连续的区间,维护区间最小值即可。

#include <bits/stdc++.h>
using namespace std; const int maxn = 1e5 + 10;
int T, n, k;
char s[maxn]; int seg[maxn * 4];
int pre[maxn];
int dp[maxn];
int len; void update(int pos, int val, int l, int r, int rt) {
if(l == r) {
seg[rt] = val;
return;
}
int mid = (l + r) / 2;
if(pos <= mid) update(pos, val, l, mid, 2 * rt);
else update(pos, val, mid + 1, r, 2 * rt + 1);
seg[rt] = min(seg[2 * rt],seg[2 * rt + 1]);
} int get(int L, int R, int l, int r, int rt) {
if(L <= l && r <= R) {
return seg[rt];
}
int left = 200000;
int right = 200000;
int mid = (l + r) / 2;
if(L <= mid) left = get(L, R, l, mid, 2 * rt);
if(R > mid) right = get(L, R, mid + 1, r, 2 * rt + 1);
return min(left, right);
} int Qu(int L, int R, int idx) {
if(L < 0) return 0;
return get(L, R, 0, len - 1, 1);
} int main() {
scanf("%d", &T);
while(T--) {
memset(pre, -1, sizeof pre);
scanf("%d%d", &n, &k);
scanf("%s", s);
len = strlen(s); pre[0] = 0;
for(int i = 1; i < len; i ++) {
pre[i] = i;
if(s[i] != s[i - 1]) pre[i] = pre[i - 1];
} for(int i = 0; i < len; i ++) {
// cout << i << " " << pre[i] << endl;
} dp[0] = 1;
update(0, dp[0], 0, len - 1, 1);
for(int i = 1; i < len; i ++) {
dp[i] = dp[i - 1] + 1;
if(i - pre[i] + 1 >= k) { } else {
if(i - k >= -1) dp[i] = min(dp[i - 1], Qu(i - k, pre[i] - 2, i)) + 1;
else if(pre[i] - 2 >= -1) dp[i] = 1;
else dp[i] = dp[i - 1] + 1;
}
update(i, dp[i], 0, len - 1, 1);
// cout << i << " " << dp[i] << endl;
}
printf("%d\n", dp[len - 1] - 1);
}
return 0;
}

2015 ACM Amman Collegiate Programming Contest 题解的更多相关文章

  1. 18春季训练01-3/11 2015 ACM Amman Collegiate Programming Contest

    Solved A Gym 100712A Who Is The Winner Solved B Gym 100712B Rock-Paper-Scissors Solved C Gym 100712C ...

  2. 2017 ACM Amman Collegiate Programming Contest 题解

    [题目链接] A - Watching TV 模拟.统计一下哪个数字最多即可. #include <bits/stdc++.h> using namespace std; const in ...

  3. ACM Amman Collegiate Programming Contest(7.22随机组队娱乐赛)

    题目链接 https://vjudge.net/contest/240074#overview 只写一下自己做的几个题吧 /* D n^2的暴力dp怎么搞都可以的 这里先预处理 i到j的串时候合法 转 ...

  4. Codeforces 2016 ACM Amman Collegiate Programming Contest B. The Little Match Girl(贪心)

    传送门 Description Using at most 7 matchsticks, you can draw any of the 10 digits as in the following p ...

  5. Codeforces 2016 ACM Amman Collegiate Programming Contest A. Coins(动态规划/01背包变形)

    传送门 Description Hasan and Bahosain want to buy a new video game, they want to share the expenses. Ha ...

  6. gym100676 [小熊骑士限定]2015 ACM Arabella Collegiate Programming Contest

    Kuma Rider久违的第二场训练,这场很水,又在vj的榜单上看到第一场的大哥了,2小时ak,大哥牛啤! A.水 #include<cstdio> #include<iostrea ...

  7. 2017 ACM Amman Collegiate Programming Contest

    A - Watching TV /* 题意:求出出现次数最多的数字 */ #include <cstdio> #include <algorithm> #include < ...

  8. 2015 ACM Arabella Collegiate Programming Contest

    题目链接:https://vjudge.net/contest/154238#overview. ABCDE都是水题. F题,一开始分类讨论,结果似乎写挫了,WA了一发.果断换并查集上,A了. G题, ...

  9. 2015 ACM Syrian Collegiate Programming Contest

    A. My Friend of Misery 计算出答案的上下界即可. 时间复杂度$O(n)$. #include<bits/stdc++.h> using namespace std; ...

随机推荐

  1. MyEclipse创建WebService服务端和客户端

    1.新建立一个javaWeb项目,一个java类,如图: 2.接下来我们就要将项目中的TestService的这个类生成WebService服务端,选择new Web Service,如图: Next ...

  2. C/S与B/S区别

    1.什么是C/S结构C/S (Client/Server)结构,即客户机和服务器结构.它是软件系统体系结构,通过它可以充分利用两端硬件环境的优势,将任务合理分配到Client端和Server端来实现, ...

  3. 五大常见的MySQL高可用方案

      1. 概述 我们在考虑MySQL数据库的高可用的架构时,主要要考虑如下几方面: 1.1 如果数据库发生了宕机或者意外中断等故障,能尽快恢复数据库的可用性,尽可能的减少停机时间,保证业务不会因为数据 ...

  4. Java SSM框架之MyBatis3(五)MyBatis之ResultMap详解

    resultMap是Mybatis最强大的元素,它可以将查询到的复杂数据(比如查询到几个表中数据)映射到一个结果集当中. resultMap包含的元素: <!--column不做限制,可以为任意 ...

  5. zabbix user parameters和Loadable modules的使用方法介绍

    目录 需求 实现 原理 前端配置 后端配置 shell实现 python实现 C实现 需求: 采集主机的-/+ buffers/cache  free的数据 实现: 采集/proc/meminfo中的 ...

  6. 洛谷 P4910 帕秋莉的手环 矩阵乘法+快速幂详解

    矩阵快速幂解法: 这是一个类似斐波那契数列的矩乘快速幂,所以推荐大家先做一下下列题目:(会了,差不多就是多倍经验题了) 注:如果你不会矩阵乘法,可以了解一下P3390的题解 P1939 [模板]矩阵加 ...

  7. 跳过复制错误——slave_skip_errors、slave_exec_mode

    这一篇写写复制错误处理相关的另两个参数slave_skip_errors.slave_exec_mode,基本环境参考<复制错误处理——sql_slave_skip_counter> 一. ...

  8. Mahalanobis距离(马氏距离)的“哲学”解释

    讲解教授:赵辉 (FROM : UESTC) 课程:<模式识别> 整理:PO主 基础知识: 假设空间中两点x,y,定义: 欧几里得距离, Mahalanobis距离, 不难发现,如果去掉马 ...

  9. 分享一个C#创建Barcode的DLL

    用于工作需要产生Barcode,随手从网上找了一个DLL(原文地址忘了) http://files.cnblogs.com/panchunting/barcode_bin.zip 使用非常简单,只需添 ...

  10. mybatis开发dao的方法——(三)

    ------------------------1.    SqlSession使用范围------------------- 1.1     SqlSessionFactoryBuilder 通过S ...