在5月5日,信友队举行了第六届图灵杯趣味网络国际邀请赛 - 初级组比赛,我在纪中参加了这场比赛。
一起来看题:
A. 寻宝之路
时间限制: 1000ms
空间限制: 262144kb
题目描述
苦苦寻宝三十载,你发现了一座古墓。
这座墓是一个环状结构,共有 𝑛n 间室,第 𝑖i 与第 𝑖+1i+1 间室,第 𝑛n 与第 11 间室之间有可双向通行的小道。
入口联通第 11 间室,价值连城的宝藏在第 𝑥x 间室。
通过一条小道需要 11 分钟。拿起宝藏不需要时间。
你现在已经从入口走到了第 11 间室,想知道最快需要多少分钟才能拿起宝藏并回到第 11 间室。
输入格式
本题有多组测试数据。
第一行输入一个数 𝑇T,表示数据组数。
接下来 𝑇T 行,每行两个正整数代表 𝑛n 和 𝑥x,表示一组数据。
输出格式
对于每组数据输出一行一个正整数,代表至少需要多少分钟才能拿到宝藏并回到第 11 间室。
样例
Input 1
5 4 2 4 4 100000 50 100000 54321 1000000000 987654321
Output 1
2 2 98 91360 24691360
数据范围
本题采用捆绑测试。
-
Subtask1(30pts),𝑛≤20n≤20;
-
Subtask2(20pts),𝑛≤105n≤105,𝑥≤50x≤50;
-
Subtask3(20pts),𝑛≤105n≤105;
-
Subtask4(30pts),无特殊限制。
对于所有数据,1≤𝑇≤201≤T≤20,1≤𝑥≤𝑛≤1091≤x≤n≤109。
样例解释
对于样例中的第一组数据,可以直接从第 11 间室移动到第 22 间室再直接返回,耗时 22 分钟。
这道题巨简单,一下子就AC了:
A | 寻宝之路 | 1277/6160 | 1389/6449 | Accepted | 100 分 |
#include<cstdio>
#include<iostream>
using namespace std;
long long t,n,x,a[1000001];
int main(){
scanf("%d",&t);
for(int i=1;i<=t;i++){
scanf("%d%d",&n,&x);
if(n-x<x-1)
a[i]=(n+1-x)*2;
else
a[i]=(x-1)*2;
}
for(int i=1;i<=t;i++)
printf("%d\n",a[i]);
}
B. 繁花
时间限制: 1000ms
空间限制: 262144kb
题目描述
Crazy 想挑选 𝑘k 朵花作为一束收藏在书房中。于是她来到花园,发现花园里有 𝑛n 朵美丽值各不相同的花,每朵花的美丽值用 𝑏𝑖bi 表示。
Crazy 想让她书房里的布置相较和谐,故对于选择的 𝑘k 朵花,她将它们按美丽值从小到大排序,得到美丽值数列 𝑎1,…,𝑎𝑘a1,…,ak。
然后她在此束中选了一朵美丽值中等的花(第 ⌈𝑘2⌉⌈2k⌉ 朵),设其美丽值为 𝑡t 。Crazy 定义这束花的不和谐度为 ∑𝑖=1𝑘(𝑎𝑖−𝑡)2∑i=1k(ai−t)2。
请你帮助 Crazy 选花,使此束花不和谐度最小,并输出这个值。
输入格式
第一行两个正整数 𝑛,𝑘n,k,表示花园里花的数量和 Crazy 想选的花的数量。
第二行 𝑛n 个互不相同的正整数 𝑏1,…,𝑏𝑛b1,…,bn,表示每朵花的美丽值。
输出格式
一行一个自然数,表示最小的不和谐度。
样例
Input 1
3 2 2 4 5
Output 1
1
Input 2
6 3 9 4 2 5 7 3
Output 2
2
数据范围
本题采用捆绑测试。
-
Subtask 1( 10 pts ):𝑘=1k=1
-
Subtask 2( 10 pts ):𝑛=𝑘n=k
-
Subtask 3( 20 pts ):𝑛≤10n≤10
-
Subtask 4( 20 pts ):𝑛≤8000n≤8000
-
Subtask 5( 40 pts ):𝑛≤2×105n≤2×105
对于所有数据,1≤𝑘≤𝑛,3≤𝑛≤2×105,1≤𝑏𝑖≤1061≤k≤n,3≤n≤2×105,1≤bi≤106
样例解释
-
在样例 1 中,Crazy 有三种选花方案,分别是 {2, 4}, {2, 5}, {4, 5},可以算出他们的不和谐度分别是 4, 9, 1,故最小不和谐度为 1。
-
在样例 2 中,选花方案可以是 {3, 4, 5},最小不和谐度为 2。
不是吧,这题根本不会做,打表得了10分
B | 繁花 | 132/9156 | 245/9884 | Wrong Answer | 10 分 |
#include<cstdio>
#include<iostream>
using namespace std;
int main(){
cout<<0;
}
C. 上传数据
时间限制: 1000ms
空间限制: 1048576kb
题目描述
出题屡屡令人不爽,尤其是上传数据传不上、不让传时。
小 M 出了一道题,试图上传数据,然而不幸的是数据可能会爆上传空间限制,于是就先挑了几个必须上传的测试点。
简单来说,数据分为 𝑛n 个 Subtask,第 𝑖i 个 Subtask 共造了 𝑝𝑖pi 个测试点。为了保证数据强度,必须上传至少 𝑤𝑖wi 个测试点。然而,由于上传数据的总空间限制,我们总计上传的测试点数不能超过 𝑚m 个。
换句话说,假设第 𝑖i 个 Subtask 上传了 𝑞𝑖qi 个数据,那么 𝑞𝑖qi 至少为 𝑤𝑖wi,最多为 𝑝𝑖pi,并且 𝑞𝑖qi 的总和不能超过 𝑚m。
在这基础上,小 M 希望最小的一个 𝑞𝑖/𝑝𝑖qi/pi 尽可能大。你可以帮帮他吗?
输入格式
第一行两个整数 𝑛,𝑚n,m。
接下来 𝑛n 行,每行两个整数 𝑝𝑖,𝑤𝑖pi,wi。
输出格式
若无方案满足,请输出 Zip file size too big after extraction.Poor M!
。
否则第一行以最简分数形式输出最大化的 𝑞𝑖𝑝𝑖piqi 最小值(形如 x/y
,使得 gcd{𝑥,𝑦}=1gcd{x,y}=1;特别地,11 为 1/1
,00 为 0/1
)。第二行输出你构造的数列 𝑞1∼𝑞𝑛q1∼qn。
注意第一行行末不可有多余空格。
样例
Input 1
10 100 1 1 11 1 45 4 14 5 19 1 26 4 8 1 17 9 19 8 1 0
Output 1
10/17 1 7 27 9 12 16 5 10 12 1
Input 2
10 3 2 0 2 0 2 0 2 0 2 0 2 0 2 0 2 0 2 0 2 0
Output 2
0/1 1 0 1 0 0 0 1 0 0 0
数据范围
所有数据保证 1≤𝑛≤1031≤n≤103,0≤𝑤𝑖≤𝑝𝑖≤𝑚≤1060≤wi≤pi≤m≤106,𝑝𝑖≠0pi=0。
对各测试点,答案正确但 𝑞𝑖qi 的方案不对的话,仅获得 20%20% 的分数。
各测试点等分。以下为各测试点额外的数据规模限制。
- 测试点 11:保证无解。
- 测试点 2∼32∼3:𝑛≤5n≤5,𝑚≤20m≤20。
- 测试点 4∼54∼5:𝑚≤4000m≤4000。
- 测试点 6∼86∼8:𝑤=0w=0。
- 测试点 9∼109∼10:无特殊限制。
样例解释
样例中构造的方案仅为一组合法解,可能还有其它可以被判定为合法的解。例如,第二组数据的方案也可以是 0 0 0 0 0 0 0 0 0 0
。
这题也是打表得了10分
#include<cstdio>
#include<iostream>
using namespace std;
int main(){
cout<<"Zip file size too big after extraction.Poor M!";
}
改题后也只有50分,大家看看怎么回事:
#include<bits/stdc++.h>
using namespace std;
int n,m,a[1000001],b[1000001],as,bs;
void dfs(){
int m1=1e9+5,m2;
for(int i=1;i<=n;++i){
if(b[i]*100/a[i]<m1&&a[i]!=b[i]){
m1=b[i]*100/a[i];
m2=i;
}
}
b[m2]++;
return;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
scanf("%d%d",&a[i],&b[i]);
as+=a[i];
bs+=b[i];}
if(bs>m){
cout<<"Zip file size too big after extraction.Poor M!";
return 0;
}
for(int i=1;i<=m-bs;++i)
dfs();
int m1,m2,m3=1e9+5;
for(int i=1;i<=n;++i){
if(b[i]*100/a[i]<m3){
m3=b[i]*100/a[i];
m1=b[i];
m2=a[i];
}
}
int t=__gcd(m1,m2);
printf("%d/%d\n",m1/t,m2/t);
for(int i=1;i<=n;++i)
cout<<b[i]<<" ";
}
D. 完全二叉树
时间限制: 1000ms
空间限制: 262144kb
题目描述
定义一棵树是合法的,当且仅当能通过若干次交换一个结点的左右儿子(可以交换空结点),使其成为一棵完全二叉树。
给定一棵根为 11 的 𝑛n 个点的二叉树。
你可以进行若干次以下三种操作:
- 删除一个叶子结点(不包括根结点)。
- 给一个没有左儿子的结点插入一个左儿子。
- 给一个没有右儿子的结点插入一个右儿子。
问使给定的树变成合法的最小操作次数。
输入格式
第一行一个整数 𝑛n,表示树的大小。
接下来的 𝑛n 行每行两个整数 𝑥𝑖,𝑦𝑖xi,yi,分别代表 𝑖i 的两个子结点号。 如果是 00 则表示没有左/右儿子。
输出格式
一行一个整数,表示答案。
样例
Input 1
5 2 4 3 0 0 5 0 0 0 0
Output 1
1
Input 2
8 7 2 0 3 4 6 5 0 0 0 0 0 0 8 0 0
Output 2
3
Input 3
8 2 0 8 3 6 4 0 5 0 0 0 7 0 0 0 0
Output 3
5
数据范围
本题采用捆绑测试。
- Subtask 1(10 pts):𝑛≤10n≤10。
- Subtask 2(15 pts):𝑛≤20n≤20。
- Subtask 3(15 pts):满足每个结点至多有一个儿子。
- Subtask 4(30 pts):𝑛≤3000n≤3000。
- Subtask 5(30 pts):无特殊限制。
对于 100%100% 的数据,1≤𝑛≤1061≤n≤106。
样例解释
对于样例 1 原树为
可以通过一步操作删除 5 号点使其变成一棵完全二叉树。
对于样例 2 原树为
我们可以通过三步操作:
删除 5 号点,给 2 号点、7 号点插入一个左儿子,并交换若干个左右儿子使其变成一棵完全二叉树。
下图形象地给出了上述三次操作后的树
注意,在这里结点的编号只是为了方便描述树的结构,实际问题中不关心结点编号。
这题打表得了15分
D | 完全二叉树 | 10/4825 | 26/4962 | Wrong Answer | 15 分 |
#include<cstdio>
#include<iostream>
using namespace std;
int main(){
int a,b,c;
cin>>a;
for(int i=1;i<=a;i++)
cin>>b>>c;
cout<<a-2;
}
题号 题目名称 赛中通过/提交数 通过提交数 我的状态 分数
A 寻宝之路 1277/6160 1389/6449 Accepted 100分
B 繁花 132/9156 248/9887 Wrong Answer 10 分
C 上传数据 106/2732 167/2998 Wrong Answer 10 分
D 完全二叉树 10/4825 26/4962 Wrong Answer 15 分
总共得了135分,在1800人中排名315,还是挺不错滴!
Byebye!