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