NOIP 2014 day1

mac2022-06-30  32

T1 生活大爆炸版剪刀石头布

题目描述 Description 石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头。如果两个人出拳一样,则不分胜负。在《生活大爆炸》第二季第8集中出现了一种石头剪刀布的升级版游戏。升级版游戏在传统的石头剪刀布游戏的基础上,增加了两个新手势:

斯波克:《星际迷航》主角之一。 蜥蜴人:《星际迷航》中的反面角色。

这五种手势的胜负关系如表一所示,表中列出的是甲对乙的游戏结果。

现在,小A和小B尝试玩这种升级版的猜拳游戏。已知他们的出拳都是有周期性规律的,但周期长度不一定相等。例如:如果小A以“石头-布-石头-剪刀-蜥蜴人-斯波克”长度为6的周期出拳,那么他的出拳序列就是“石头-布-石头-剪刀-蜥蜴人-斯波克-石头-布-石头-剪刀-蜥蜴人-斯波克-„„”,而如果小B以“剪刀-石头-布-斯波克-蜥蜴人”长度为5的周期出拳,那么他出拳的序列就是“剪刀-石头-布-斯波克-蜥蜴人-剪刀-石头-布-斯波克-蜥蜴人-„„”

已知小A和小B一共进行N次猜拳。每一次赢的人得1分,输的得0分;平局两人都得0分。现请你统计N次猜拳结束之后两人的得分。

输入描述 Input Description

输入文件名为rps.in。

第一行包含三个整数:N,NA,NB,分 别 表 示 共 进 行N次猜拳、小A出拳的周期长度,小B出拳的周期长度。数与数之间以一个空格分隔。

第二行包含NA个整数,表示小A出拳的规律,第三行包含NB个整数,表示小B出拳的规律。其中,0表示“剪刀”,1表示“石头”,2表示“布”,3表示“蜥蜴人”, 4表示“斯波克”。数与数之间以一个空格分隔。

输出描述 Output Description

输出文件名为rps.out。

输出一行, 包含两个整数,以一个空格分隔,分别表示小A、小B的得分。

样例输入 Sample Input

样例输出 Sample Output

数据范围及提示 Data Size & Hint 对于100%的数据,0 < N ≤ 200,0 < NA ≤ 200, 0 < NB ≤ 200。

就是想看你会不会编程……if练习……

T2 联合权值

题目描述 Description

输入描述 Input Description

输出描述 Output Description

样例输入 Sample Input

样例输出 Sample Output

数据范围及提示 Data Size & Hint

题目要求分别求出最大值和总和,首先要做枚举距离为二的点对……最大值很好找,只要找到最大值和次大值就好了,和的话……我们知道,要求的是,即 tips:

#include <bits/stdc++.h> using namespace std; typedef long long LL; const int SZ = 200020; const int mod = 10007; struct Edge { int f, t; }es[SZ << 1]; int first[SZ << 1], nxt[SZ << 1], tot = 1, fee[SZ]; int ri[SZ]; bool vis[SZ]; LL ans, maxn; queue<int> q; void build(int f, int t) { es[++tot] = (Edge){f, t}; nxt[tot] = first[f]; first[f] = tot; ri[f]++; } LL search(int u) { int first_one = 0, second_one = 0, first_num, second_num; LL All_Sum = 0; for(int i = first[u]; i; i = nxt[i]) { int v = es[i].t; if(fee[v] > first_one) { first_one = fee[v]; first_num = v; } All_Sum += fee[v]; } for(int i = first[u]; i; i = nxt[i]) { int v = es[i].t; if(fee[v] > second_one && v != first_num) { second_one = fee[v]; second_num = v; } } for(int i = first[u]; i; i = nxt[i]) { int v = es[i].t; ans = (ans % mod + ((All_Sum - fee[v]) % mod * (fee[v] % mod) % mod)) % mod; } return first_one * second_one; } int read() { char c = getchar(); while(c < '0' || c > '9') c = getchar(); int num = 0; while('0' <= c && c <= '9') { num = num * 10 + c - '0'; c = getchar(); } return num; } int main() { int n, f, t; n = read(); for(int i = 1; i < n; i++) { f = read(); t = read(); build(f, t); build(t, f); } for(int i = 1; i <= n; i++) fee[i] = read(); for(int i = 1; i <= n; i++) if(ri[i] >= 2) maxn = max(maxn, search(i)); printf("%lld %lld", maxn, ans); return 0; }

T3 飞扬的小鸟

题目描述 Description

输入描述 Input Description

输出描述 Output Description

输出文件名为 bird.out。

共两行。

第一行,包含一个整数,如果可以成功完成游戏,则输出 1,否则输出 0。

第二行,包含一个整数,如果第一行为 1,则输出成功完成游戏需要最少点击屏幕数,

否则,输出小鸟最多可以通过多少个管道缝隙。

样例输入 Sample Input

样例输出 Sample Output

【输入输出样例说明】

如下图所示,蓝色直线表示小鸟的飞行轨迹,红色直线表示管道。

数据范围及提示 Data Size & Hint 对于 30%的数据:5≤n≤10,5≤m≤10,k=0,保证存在一组最优解使得同一单位时间最多点击屏幕 3 次;

对于 50%的数据:5≤n≤20,5≤m≤10,保证存在一组最优解使得同一单位时间最多点击屏幕 3 次;

对于 70%的数据:5≤n≤1000,5≤m≤100;

对于 100%的数据: 5≤n≤10000, 5≤m≤1000, 0≤k

#include <iostream> #include <cstdio> #include <cstring> using namespace std; int X[10001], Y[10001], up[10001], down[10001], dp[10001][1001]; int read() { char c = getchar(); while(c < '0' || c > '9') c = getchar(); int num = 0; while('0' <= c && c <= '9') { num = num * 10 + c - '0'; c = getchar(); } return num; } int n, m, k, pass = 0, x; bool flag; int main() { n = read(), m =read(), k = read(); for(int i = 0; i < n; i++) X[i] = read(), Y[i] = read(); for(int i = 0; i <= n; i++) up[i] = m + 1, down[i] = 0; for(int i = 1; i <= k; i++) { x = read(); down[x] = read(); up[x] = read(); } memset(dp, 0x7f, sizeof(dp)); int maxn = dp[0][0]; for(int i = 1; i <= m; i++) dp[0][i] = 0; for(int i = 1; i <= n; i++) { flag = 0; for(int j = X[i- 1] + 1; j <= m; j++) { if(j != m) dp[i][j] = min(min(dp[i][j], dp[i - 1][j - X[i - 1]] + 1), dp[i][j - X[i - 1]] + 1); else { for(int k = m - X[i - 1]; k <= m; k++) dp[i][j] = min(min(dp[i][j], dp[i - 1][k] + 1), dp[i][k] + 1); } } for(int j = 0; j <= down[i]; j++) dp[i][j] = maxn; for(int j = up[i]; j <= m; j++) dp[i][j] = maxn; for(int j = down[i] + 1; j < up[i]; j++) { if(j + Y[i - 1] <= m) dp[i][j] = min(dp[i][j], dp[i - 1][j + Y[i - 1]]); if(dp[i][j] < maxn) flag = 1; } if(!flag) { printf("0\n%d", pass); return 0; } if(up[i] != m + 1) pass++; } pass = maxn; for(int i = down[n] + 1; i < up[i]; i++) if(dp[n][i] < pass) pass = dp[n][i]; printf("1\n%d", pass); return 0; }

转载于:https://www.cnblogs.com/Loi-Vampire/p/6017041.html

相关资源:NOIP2014提高组官方数据
最新回复(0)