北京信息科技大学第十三届程序设计竞赛暨ACM选拔赛题解
北京信息科技大学第十三届程序设计竞赛暨ACM选拔赛题解
- A lzh的蹦床
- B 所谓过河
- C 旅行家问题1
- D 旅行家问题2
- E 小菲和Fib数列
- F 好玩的音乐游戏
- G ranko的手表
- H 字母收集
- I 数字染色
- J 小红的心愿
- K 小红的树
- L 重排字符串
A lzh的蹦床
sky被lzh抓到了一间密室,密室里放了一排紧密相邻的蹦床 ,lzh声称自己最喜欢欣赏sky跳跃在空中的姿态,并示意他可以开始跳了。sky的跳跃方向是单向向前的,当然如果他落到一个蹦床上则会继续向前弹跳,直到sky落到了坚硬可靠的地面上,他才可以结束这一趟弹跳,lzh当然允许sky自己选择每一趟跳跃开始的蹦床。
每一个蹦床都有它的弹力值 bi,这决定了从该蹦床起跳后的落点–通俗来说,从i 蹦床起跳将会落到 i+bi蹦床上(假如这个位置有蹦床)。但由于sky心中有怨气,他便不会爱惜的使用lzh珍藏已久的蹦床,可惜的是,他每一次的起跳都会造成当前蹦床的弹力值 -1,但幸好lzh的蹦床是为了sky的安全设计的,也就是说,这个蹦床的弹力值不会低于 1 。sky饿的不行了,他想尽早回宿舍,他观察到lzh对他进行距离为 1 的跳跃(也就是从 ai 跳到 ai+1)不怎么感兴趣,他打算使所有蹦床弹力值都变成 11 ,这样他就可以回宿舍吃饭了,请你帮帮他,计算出他最少需要跳多少趟。
输入描述:
第一行输入一个正整数 T(T≤500),表示测试用例的个数,接下来 T 个用例,
每个用例第一行一个正整数 n(1≤n≤5000),表示蹦床的数量;
第二行有 n 个正整数 bi(1≤bi≤1e9),表示每个蹦床的弹力值。
输出描述:
对于每组用例,输出一个整数,表示sky最少需要跳多少趟
示例:
输入:
3
7
1 4 2 2 2 2 2
2
2 3
5
1 1 1 1 1
输出:
4
3
0
代码:
#include <bits/stdc++.h>
#define mem(a) memset(a,0,sizeof(a))
int a[10050], b[10050], c[10050];
int main()
{int t; si(t);while (t--){int n; si(n); ll ans = 0; mem(b); mem(c);for (int i = 1; i <= n; i++) si(a[i]);for (int i = 1; i <= n; i++){c[i] += c[i - 1]; b[i] += c[i];ans += max(0, a[i] - b[i] - 1); b[i] = max(b[i], a[i] - 1);b[i + 1] += b[i] - a[i] + 1; if (a[i] > 1)c[i + 2]++, c[min(i + a[i]+1, n + 1)]--;}printf("%lld\n", ans);}return 0;
}
B 所谓过河
sky一到饭点便冲向了食堂,刚学会魔法的lzh见状,在他和食堂之间变出了一条无限长的大河( 宽当然是有限的 )。
幸运的是,lzh的魔法还不够精妙,长河中还留有 NN 个残余的圆形石头(重叠部分厚度不计),
sky可以踩在上面过河,当然他不能在石头之间跳远,只有两个圆形石头相交(有重叠部分或紧贴)他才能在这两块石头上来回移动,
同样他只能通过与岸边相交的石头才能上岸或者进入河中。 sky想知道他能不能到达河对面,请你帮帮他。
输入描述:
第一行包括两个整数 N ,H ,表示石头的个数和河的宽度(1≤N≤10000,1≤H≤1e9)。
sky所在的河岸边可以看作 的直线,河对面的岸可看作 的直线。
接下来 NN 行每一行包括三个整数 xi,yi,ri;分别表示每块石头的圆心坐标以及半径,保证所有石头的圆心都在河中。(0≤∣xi∣,∣yi∣≤1e9,1≤ri≤1e9)
输出描述:
如果sky能到河对面,输出”Yes“,反之输出”No“
示例:
输入:
2 3
1 1 1
1 3 1
输出:
Yes
代码:
#include <bits/stdc++.h>
#define si(a) scanf("%d",&a)
#define sf(a) scanf("%lf",&a)
int b[10010]; int fa[10010];
struct dian
{double x, y, z;bool friend operator <(dian a, dian b){if(a.y!=b.y)return a.y-a.z < b.y-b.z;}
}a[10010];
bool check(dian a, dian b)
{return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)) <= a.z + b.z;
}
int main()
{int n, h; si(n), si(h); bool f = 0;for (int i = 1; i <= n; i++){sf(a[i].x), sf(a[i].y), sf(a[i].z); fa[i] = i;}sort(a + 1, a + n + 1);for (int i = 1; i <= n; i++){if (a[i].z >= a[i].y)b[i] = 1;if (a[i].y + a[i].z >= h)if (b[i])f = 1;elseb[i] = 2;}for (int i = 1; i < n; i++)for (int j = i + 1; j <= n; j++)if (check(a[i], a[j]))fa[j] = i;for (int i = 1; i <= n; i++){int now = i;while (fa[now] != now)now = fa[now];if (b[i]*b[now] == 2)f = 1;}f ? puts("Yes") : puts("No");return 0;
}
C 旅行家问题1
lzh最近在学习旅行家问题,为了照顾太菜的他,学长给他出了一个一维的问题,好让他对生活抱有希望。在一个数轴上面,散落着 n 个城市,每个城市的坐标由 xi表示。
给定旅行家的坐标,他每走一个单位长度需要的时间为1s,求他访问所有城市需要的最小时间。
输入描述:
第一行包含两个正整数 n ,x (1≤n≤2e5,1≤x≤1e9)表示需要访问的城市数量以及lzh最初所在城市的坐标。
第二行包含 n 个正整数 xi (1≤xi≤1e9),表示要访问的城市的位置坐标。
输出描述:
输出一个正整数,代表旅行家访问所有城市需要的最短时间。
示例:
输入:
2 3
2 4
输出:
3
代码:
#include <bits/stdc++.h>
#define si(a) scanf("%d",&a)
int main()
{int n, x, num, maxn=0, minn=1e9;si(n), si(x);while (n--){si(num);maxn = max(maxn, num), minn = min(minn, num);}if (x < minn)printf("%d\n", maxn - x);else if (x > maxn)printf("%d\n", x - minn);elseprintf("%d\n", maxn - minn + min(x-minn,maxn-x));return 0;
}
D 旅行家问题2
显然,身为旅行家,爬山是他不能回避的问题。地图上存在 N 座高度 hi,由于这些山实在是太高惹,他们的宽度和彼此之间的距离都可以忽略不计。每座山的山顶存在一个高为 xi 的梯子,
他可以通过这个梯子到达高度可及的山顶,通俗的来说从高山i的山顶,可以转移到 hj ≤hi+xi 的高山j的山顶上去,同时交付 xi的梯子使用费。如果他想达到当前山顶的梯子高度所不能及的高山,他便需要搭乘飞机并交纳 hj−hi的运输费。
旅行家从一号山出发,他需要访问所有高山并返回一号山,请你帮他设计一个路线,使他花费的费用最小。
输入描述:
第一行包含一个整数 N。(2≤N≤1e5) 接下来 N 行,第 i 行包括两个正整数 hi,xi (1 ≤ i ≤ N,0 ≤ hi,xi ≤ 1e9),表示第 i 个山的高度,山顶梯子的长度。
输出描述:
输出一个正整数,表示最小的花费。
示例:
输入:
3
1 9
2 1
4 1
输出:
11
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){pair <int, int> a[100010]; int n; ll ans = 0; cin >> n;for (int i = 0; i < n; i++) cin>>a[i].first>>a[i].second, ans += a[i].second;sort(a, a + n); int h = a[0].first + a[0].second;for (int i = 1; i < n; i++) { if (a[i].first > h) ans += a[i].first - h; h = max(h, a[i].first + a[i].second); }printf("%lld\n", ans);return 0;
}
E 小菲和Fib数列
小菲喜欢上了Fibonacci数列,该数列的通项公式为f(1)= 1, f(2) = 1,f(i) = f(i-1)+f(i-2) (i≥3),他试图对该数列进行她独特的求和方式,即对数列中所有本质不同的二元组进行如下运算(%为取模运算),并对所有本质不同的二元组的运算结果进行加和。
注:本质不同的二元组为组内两个元素的下标是该数列元素下标的唯一组合。
输入描述:
输入一个正整数(1≤N≤5e4),表示数列元素的个数。
输出描述:
输出一个正整数,表示用小菲的运算方式得到的答案。
示例:
输入:
4
输出:
3
代码:
#include <bits/stdc++.h>
typedef long long ll;
#define si(a) scanf("%d",&a)
int a[50010], b[50010];
int main()
{a[1] = a[2] = 1;for (int i = 3; i <= 5e4; i++){a[i] = (a[i - 2] + a[i - 1]) % 2;b[i] = b[i - 1] + !a[i];}int n; si(n); ll ans = 0;for (int i = 1; i <= n; i++)if (!a[i]) ans += i - 1;else ans += b[i - 1];printf("%lld\n", ans);return 0;
}
F 好玩的音乐游戏
小红最近迷上了一个好玩的音乐游戏——邦多利。她玩了一段时间之后,决定自己制作音游的谱面。于是,她打开了一个谱面制作器:
已知音符一共有2种类型:
1.点击(tap),用大写字母O表示。
2.滑动(也称粉键,flick),用大写字母X表示。
在同一时间如果有两个音符同时出现,需要用连接线把它们连接起来(除非他们是相邻的两个音符就不用连)。
小红输入了一些时间和该时间应出现的音符,请你将谱面打印出来。
ps:谱面一共有7个轨道可以用来放置音符!
输入描述:
第一行为两个正整数 n 和 m ,代表音符的数量以及歌曲的长度。(1≤n,m≤2000)接下来的 n 行,每行由一个字符串 si和两个正整数ti
,hi组成,分别代表音符的类型、音符出现的时间以及音符所在的音轨位置。(1≤ti≤m,1≤hi≤7,且 si一定是tap或flick中的一个单词)
保证输入合法,即不会在同一时间的同一个音轨出现两个以上音符,也不会同一时间出现超过2个音符。
输出描述:
一共 m+1 行字符串,用来表示谱面。谱面最底部有一行固定的字符串 ±------+ 表示谱面开始,这一行不计入歌曲总时间。
谱面开始以后,每一行表示一个时刻,一行中有 7 个字符(只可能是空格、大写字母O、大写字母X、短横线中的一种)被包含在两个竖线(|)之间表示当前时刻 7 个音轨的状态。
如果在同一时刻,相邻的两个音轨出现音符,则不需要再绘制短横线进行连接。
示例:
输入:
3 10
tap 2 1
tap 5 6
flick 2 4
输出:
| |
| |
| |
| |
| |
| O |
| |
| |
|O--X |
| |
+-------+
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 2010;
string s[N];
int n, m;
int main() {cin >> n >> m;s[0] = "+-------+";for(int i=1; i<=m; i++) s[i] = "|-------|";for(int i=0; i<n; i++) {string tmp; int t, h; cin >> tmp >> t >> h;if(tmp == "tap") s[t][h] = 'O';else s[t][h] = 'X';}for(int i=1; i<=m; i++) {for(int j=1; j<=7; j++) {if(s[i][j] != '-') break;s[i][j] = ' ';}for(int j=7; j>=0; j--) {if(s[i][j] != '-') break;s[i][j] = ' ';}}for(int i=m; i>=0; i--) cout << s[i] << endl;return 0;
}
G ranko的手表
ranko 的手表坏了,正常应该显示 xx:xx 的形式(4 个数字),比如下午 1 点半应该显示 13:30 ,但现在经常会有一些数字有概率无法显示。
ranko 在 t1时刻看了下时间,过了一段时间在 t2时刻看了下时间。她想知道, t1和 t2这两个时刻之间相距的时间的最大值和最小值是多少?
保证 t1在 t2之前(且 t1和 t2不等)。t1和 t2在同一天的 00:00 到 23:59 之间。
输入描述:
两行输入两个时间,为 xx:xx 的形式。其中 xx 为数字或者字符 ‘?’ ,问号代表这个数字没有显示。
保证输入是合法的。
输出描述:
一行输出两个整数,分别代表 t1和 t2相距时间的最小值和最大值(单位分钟)。
示例:
输入:
18:0?
2?:1?
输出:
121 319
代码:
#include<bits/stdc++.h>
using namespace std;
int main(){int j,i;string s1,s2;cin>>s1>>s2;vector<int>v1,v2;for(i=0;i<24*60;i++){int h=i/60,m=i%60;if((h/10==s1[0]-'0'||s1[0]=='?')&&(h%10==s1[1]-'0'||s1[1]=='?')&&(m/10==s1[3]-'0'||s1[3]=='?')&&(m%10==s1[4]-'0'||s1[4]=='?'))v1.push_back(i);if((h/10==s2[0]-'0'||s2[0]=='?')&&(h%10==s2[1]-'0'||s2[1]=='?')&&(m/10==s2[3]-'0'||s2[3]=='?')&&(m%10==s2[4]-'0'||s2[4]=='?'))v2.push_back(i);}int mi=1e9,ma=0;for(i=0;i<v1.size();i++){for(j=0;j<v2.size();j++){if(v1[i]<v2[j]){ma=max(ma,v2[j]-v1[i]);mi=min(mi,v2[j]-v1[i]);}}}cout<<mi<<" "<<ma<<endl;
}
H 字母收集
有一个 n∗m 的矩形方阵,每个格子上面写了一个小写字母。
小红站在矩形的左上角,她每次可以向右或者向下走,走到某个格子上就可以收集这个格子的字母。
小红非常喜欢 “love” 这四个字母。她拿到一个 l 字母可以得 4 分,拿到一个 o 字母可以得 3 分,拿到一个 v 字母可以得 2 分,拿到一个 e 字母可以得 1 分。
她想知道,在最优的选择一条路径的情况下,她最多能获取多少分?
输入描述:
1≤n,m≤500
接下来的 n 行 每行一个长度为 m 的、仅有小写字母构成的字符串,代表矩形方阵。
输出描述:
小红最大可能的得分。
示例:
输入:
3 2
ab
cd
ef
输出:
1
代码:
#include <bits/stdc++.h>
using namespace std;
#define si(a) scanf("%d",&a)
int a[510][510];
int main()
{int n, m; si(n), si(m);for(int i=1;i<=n;i++)for (int j = 1; j <= m; j++){char c; cin >> c;a[i][j] = max(a[i - 1][j], a[i][j - 1]);if (c == 'l')a[i][j] += 4;else if (c == 'o')a[i][j] += 3;else if (c == 'v')a[i][j] += 2;else if (c == 'e')a[i][j]++;}printf("%d\n", a[n][m]);return 0;
}
I 数字染色
小红拿到了一个由正整数组成的数组,她准备把这个数组上的某些数染成红色。
但是有一个限制,染成红色的所有的数的 gcd (最大公约数)必须大于 1 。
小红想知道,自己有多少种不同的染色方案?
我们定义,若两种方案染色的数的数量不同,或者有两个数的染色状态不同,那么则视为两种不同的方案。
这个方案数可能过大,请对 1e9+7 取模。
输入描述:
第一行一个正整数 n ,代表数组的大小。
第二行有 n 个正整数 ai,表示数组。
1≤n,ai≤1e5
输出描述:
染红色数字的方案数,对 1e9+7 取模。
示例:
输入:
4
2 3 6 2
输出:
9
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+5,mod=1e9+7;
ll a[N],in[N],T[N],num[N],prim[N],idx=0;
bool dis[N];
void add(ll &a,ll b) {a=(a+b)%mod;}
int main()
{in[0]=1;for(int i=1;i<N;i++) add(in[i],in[i-1]*2);ll n,nu,ans=0;scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&nu),a[nu]++;for(int i=1e5;i>=2;i--){ll x=a[i]; for(int j=i+i;j<=1e5;j+=i)add(T[i],-T[j]),x+=a[j];add(T[i],in[x]-1);add(ans,T[i]);}add(ans,mod);cout<<ans<<endl;return 0;
}
J 小红的心愿
小红很喜欢红色。
有一天她来到了北京信息科技大学校赛的现场,她带来了个气球,其中有一些是红气球。她想把红色的气球送给这场比赛做出这道题的人。
这道题只需要需要你输出一个正整数,代表字符串"redballoon"的长度即可。
你可以帮她完成这个心愿吗?
输入描述:
无
输出描述:
一个正整数。
代码:
#include <bits/stdc++.h>
int main()
{puts("10");return 0;
}
K 小红的树
小红拿到了一棵有根树。根节点为1号节点。
所谓树,指没有回路的无向连通图。
现在小红想给一部分点染成红色。之后她有 次询问,每次询问某点的子树红色节点的个数。
输入描述:
第一行一个正整数 n ,代表树的节点个数。
第二行有 n−1 个正整数,分别表示第 2 个节点到第 n 个节点每个节点的父亲。
接下来一个长度为 n 的、由’W’或’R’字符组成的字符串。第 i 个字符为’W’代表该字符没被染色,若字符为’R’代表该字符被染成了红色。
接下来一个正整数 q ,代表小红的询问次数。
接下来的 q 行,每行有一个正整数 xx ,代表一次询问。
(1≤n,q≤1e5,1≤x≤n)
输出描述:
对于每次询问,输出一个整数,代表节点xx的子树的红色节点个数。
示例:
输入:
5
1 2 1 4
WRWRR
3
3
4
5
输出:
0
2
1
代码:
#include <bits/stdc++.h>
using namespace std;
#define si(a) scanf("%d",&a)
int f[100010], a[100010];
int main()
{int n; si(n); f[1] = 1;for (int i = 2; i <= n; i++)si(f[i]);for (int i = 1; i <= n; i++){char c; cin >> c;if (c == 'R'){int now = i;while (f[now] != now){a[now]++;now = f[now];}a[now]++;}}int q; si(q);while (q--){int n; si(n);printf("%d\n", a[n]);}return 0;
}
L 重排字符串
小红拿到了一个只由小写字母组成的字符串。她准备把这个字符串重排(只改变字母的顺序,不改变数量)
重排后小红想让新字符串不包含任意两个相同的相邻字母。
你能帮帮她吗?
输入描述:
第一行一个正整数 n ,代表字符串的长度。 (1≤n≤1e5)
第二行为一个长度为 n 的、只由小写字母组成的字符串。
输出描述:
如果可以完成重排,请在第一行输出一个“yes”,第二行输出重排后的字符串。如果有多个正解,输出任意即可。
如果不能重排,则直接输出“no”
示例:
输入:
7
aabbccc
输出:
yes
cabcabc
代码:
#include <bits/stdc++.h>
using namespace std;
int n; string s; priority_queue <pair<int, char>, vector<pair<int, char> >, less<> >q; int a[30]; pair <int, char> p,o;
int main()
{cin >> n >> s; bool f = 1;for (int i = 0; i < n; i++)a[s[i] - 'a']++;s.clear();for (int i = 0; i < 30; i++)if (a[i]) q.push({ a[i], 'a' + i });p = q.top(); q.pop();s += p.second; p.first--;while (q.size()){o = q.top(); q.pop();s += o.second; o.first--;if (p.first)q.push(p);p = o;}if (p.first)puts("no");else{puts("yes");cout << s << endl;}return 0;
}
北京信息科技大学第十三届程序设计竞赛暨ACM选拔赛题解相关推荐
- 北京信息科技大学第十三届程序设计竞赛暨ACM选拔赛(重现赛)题解
题目链接: 北京信息科技大学第十三届程序设计竞赛暨ACM选拔赛(重现赛)_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ大学ACM校赛新生赛是面向ACM/ICPC/CCP ...
- 2018年北京信息科技大学第十届程序设计竞赛暨ACM选拔赛 A题题解
链接: https://www.nowcoder.com/acm/contest/118/A 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言655 ...
- 2018年北京信息科技大学第十届程序设计竞赛暨ACM选拔赛题解
链接:https://www.nowcoder.com/acm/contest/118/A 来源:牛客网 PUBG 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语 ...
- 2018年北京信息科技大学第十届程序设计竞赛暨ACM选拔赛 H 程序员的好印象
题意: 有一个0,1的序列,当你出现1之后就不能在出现0了,问你最长的子序列长度是多少 思路:0 0 0 1 1 1 ,1之后不能出现0了,那其实就是最长上升子序列啊没了... 代码: #inclu ...
- E-游戏机本当下手(北京信息科技大学第十二届程序设计竞赛暨ACM选拔赛)
游戏机本当下手 题目: 藤原妹红拿到了一个游戏机,游戏机上有'1'和'0'两个按钮. 妹红发现,只要按住某个按钮不放,屏幕上就能一直不断打印那个字符. 比如对于"11111111100000 ...
- 北京信息科技大学第十二届程序设计竞赛暨ACM选拔赛(同步赛)
A .爱丽丝的人偶(一) 链接:https://ac.nowcoder.com/acm/contest/8755/A 来源:牛客网 题目描述 爱丽丝有n个人偶,每个人偶的身高依次是 1,2,3,-n ...
- 北京信息科技大学第十二届程序设计竞赛暨ACM选拔赛题解
A 爱丽丝的人偶(一) 链接:https://ac.nowcoder.com/acm/contest/8755/A 题目描述 爱丽丝有个人偶,每个人偶的身高依次是 现在她要将这个人偶摆成一排. 但是人 ...
- 海淀区第九届单片机竞赛获奖名单_第十二届程序设计竞赛暨ACM选拔赛获奖名单...
11月21日由北京信息科技大学ACM集训队主办,计算机学院承办,牟永敏老师指导的第十二届程序设计竞赛暨ACM选拔赛完美落幕.本次比赛的参赛队员来自北信科的各个学院的同学共同参与,共142人报名参与此次 ...
- 第十三届蓝桥杯Python B组国赛题解
第十三届蓝桥杯Python B组国赛题解 试题A:斐波那契与7 试题 B: 小蓝做实验 试题 C: 取模 试题 D: 内存空间 试题 E: 近似 GCD 试题 F: 交通信号 试题 G: 点亮 试题 ...
最新文章
- 锚定比特币现金(BCH),助力构建价值互联网时代
- python做表格计算公式_Python自学Day45 制作Excel报表
- DSP5509项目之用FFT识别钢琴音调(1)
- 《卓有成效的程序员》读书笔记
- 设计模式之动态代理模式实战
- Element UI格式化日期
- java调python 监控_利用Python实现一个简单的系统监控图表
- Quantaxis更新数据到最新
- 指向函数的指针数组(C++)
- hibernate级联删除问题
- python编程入门指南-《中小学生Python编程入门指南》3.4 字典
- winform通过WebClient调用api接口
- 超级搜索术3-吸收应用/一键直达
- 利用云服务器自动发送天气预报邮件
- bigemap离线手机离线地图的查看
- JZOJ 3339. 【NOI2013模拟】wyl8899和法法塔的游戏【NIM博弈】【暴力】
- [开源 .NET 跨平台 数据采集 爬虫框架: DotnetSpider] [一] 初衷与架构设计 - ModestMT.Zou - 博客园...
- 阿里云服务器搭建wordpress个人博客
- 合并k个有序链表 python_Leetcode打卡 | No.23 合并 k 个有序链表
- 全光谱台灯对孩子有伤害吗?儿童用台灯的好处和坏处是什么