A题
众所周知,wy学姐心灵手巧,她最近在学习原画,立志往国风和赛博朋克风格发展。
绘画的工具是很重要哒!
于是思量再三+长期吃土后,她买了一支biulingbiuling~闪的魔法棒画笔,由于刚刚接触,wy学姐还没有领悟到其中的奥秘所在,她只会以普通画笔的方式去使用它。
wy学姐决定用它来练习画直线,于是她在平面直角坐标系中画出了如下的图形:
善于思考的wy学姐发现!她随手一画的图竟然是有点规则的!!OMG!!!
于是她决定考考你是否也发现了这个神奇美妙的规则,是否感悟到了数学的诱人的魅力和本质?
wy学姐会随机给出两个点,要求你算出连接两点的折线长度(即沿折线走的路线长度)。
Input
第一个数是正整数N(≤100)。代表数据的组数。
每组数据由四个非负整数组成x1,y1,x2,y2;所有的数都不会大于100。
Output
对于每组数据,输出两点(x1,y1),(x2,y2)之间的折线距离。注意输出结果精确到小数点后3位。
Sample Input
5
0 0 0 1
0 0 1 0
2 3 3 1
99 99 9 9
5 5 5 5
Sample Output
1.000
2.414
10.646
54985.047
0.000
思路:找规律
规律即
(0,0)到(1,0)的距离是sqrt(1.0*1*1+1.0*(1-1)*(1-1))+sqrt(1.0*1*1+1.0*1*1)=1
(0,1)到(2,0)地距离是sqrt(1.0*2*2+1.0*(2-1)(2-1))+sqrt(1.0*2*2+1.0*2*2)…….
可设数组a[i](即(0,0)到(i,0);
A[i]=a[i-1]+ sqrt(1.0*i*i+1.0*(i-1)*(i-1))+sqrt(1.0*i*i+1.0*i*i);
设r为(0,0)到(x1,y1)的距离 ;y为(0,0)到(x2,y2)的
m=x1+y1-1;(x1,y1)坐标前面(m,0)
r=a[m]+sqrt(1.0*m*m+1.0*(m+1)*(m+1))+sqrt(1.0*x1*x1+1.0*(m+1-y1)*(m+1-y1))
m=x2+y2-1;
y=a[m]+sqrt(1.0*m*m+1.0*(m+1)*(m+1))+sqrt(1.0*x2*x2+1.0*(m+1-y2)*(m+1-y2));
y-r即为完整距离。
A.
多观察图形,得到找到规律,特点,公式
#include<stdio.h>
#include<math.h>
int main() {
int i,j,k,n,m,t;
double a[220];
a[0]=0;
for(i=1;i<=210;i++) //a[i]表示(0,0)到(i,0)的距离
a[i]=a[i-1]+sqrt(1.0*i*i+1.0*(i-1)*(i-1))+sqrt(1.0*i*i+1.0*i*i);
int x1,y1,x2,y2;
scanf("%d",&t);
while(t--) {
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
double r,y; //r为(0,0)到(x1,y1)的距离 ;y为(0,0)到(x2,y2)的距离
if(x1==0&&y1==0)
r=0;
else {
m=x1+y1-1;
r=a[m]+sqrt(1.0*m*m+1.0*(m+1)*(m+1))+sqrt(1.0*x1*x1+1.0*(m+1-y1)*(m+1-y1));
}
if(x2==0&&y2==0)
y=0;
else {
m=x2+y2-1;
y=a[m]+sqrt(1.0*m*m+1.0*(m+1)*(m+1))+sqrt(1.0*x2*x2+1.0*(m+1-y2)*(m+1-y2));
}
printf("%.3f\n",fabs(y-r)); //y-r即为完整距离
}
return 0;
}
C题
众所周知,yh学长 is very rich,他靠着玩超级大富翁的游戏富上加富,买下了地球的半座江山(另外半座他不想要啦!)。
Of course,yh学长啥都有,这其中当然也包括养猪场。
这天,yh学长正在养猪场里跟它们一起玩,他心血来潮点了个到:“花花、茉莉、小爱、仙子……???仙子呢?!Where are my dear Xianzi???!!!”
yh学长忽然发现名为“仙子”的小粉猪不见了!Oh no!这可是他最心爱的一头猪!!!
幸好yh学长在每只猪的身上都安装了高级GPS定位导航,通过智能腕表,他可以实时知道“仙子”的位置。
yh学长从一条直线上的一个点N (0 ≤ N ≤ 100,000) 开始,“仙子”在同一直线上的一个点K (0 ≤ K ≤ 100,000) 上。
yh学长迫不及待地想把“仙子”带回来,他决定现在就出发去找它。
可是作为一个 richer ,可选择的交通方式实在是太多了,到底要用什么交通方式去找呢?
yh学长想起“仙子”最爱的两个交通工具—— 南瓜老年代步车 以及 超级无敌霹雳豪华完美小巧简易宇宙飞船。
南瓜老年代步车南瓜老年代步车——yh学长可以在一分钟内从任何一点X移动到X-1或X+1两点。
超级无敌霹雳豪华完美小巧简易宇宙飞船超级无敌霹雳豪华完美小巧简易宇宙飞船——yh学长可以在一分钟内从任何X点移动到2*X点。
已知“仙子”在离家出走一段时间后就反悔了,
十分地想念yh学长(这就是双向奔赴吗(T▽T)磕到了磕到了ヾ(◍°∇°◍)ノ゙),
但它太累了,于是决定在原地不动等yh学长来找它。
请问yh学长至少需要多长时间才能把它找回来?
Input
第一行输入两个整数 N 和 K
Output
输出一个整数——yh学长至少花多长时间才能把“仙子”找回来?
Sample Input
5 17
Sample Output
4
yh学长到达“仙子”所在地的最快方法是沿着以下路径移动:5-10-9-18-17,这需要4分钟。
思路:
可供选择方案有3种
:在当前位置:1前进1;2后退1;3当前位置的2倍。
由此可得两种情况:
1.N>K时仅能选后退1,答案即N-K;
2.N<K时定义2个数组:
1.bool vis[N](未经过为false;经过为true)判断是否经过此点避免反复;
2. int step[N];记录到了每一位置所走的步数;
建立一个队列,当前位置n入队,并记录step[n]=0;
将队列中的数值(设为head)取出并进行3种方案运算结果(这个结果要满足vis[结果]=false)入队并改变vis[结果]=true,并且step[ (满足条件的结果)]=step[head]+1;反复以上操作直到有运算结果出现K;输出step[K];
#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<map>
#include<queue>
#include<algorithm>
#include<memory.h>
using namespace std;
typedef long long ll;
const int N = 1e5+5;
bool vis[N]; //标记数组
int step[N]; //记录到了每一位置所走的步数
queue<int> q; //定义队列
int bfs(int n, int k)
{
int head, next;
q.push(n); //开始在n位置,n入队
step[n] = 0;
vis[n] = true; //标记已访问
while(!q.empty())
{
head = q.front();
q.pop();
for (int i = 0; i < 3; ++i) //三种走法
{
if(i == 0)
next = head - 1;
else
if(i == 1)
next = head + 1;
else
next = head * 2;
if(next < 0 || next >= N) //排除出界情况
continue;
if(!vis[next]) //如果next位置未被访问
{
q.push(next); //入队
step[next] = step[head] + 1; //步数+1
vis[next] = true; //标记已访问
}
if(next == k) //当遍历到结果,返回步数
return step[next];
}
}
}
int main()
{
int n, k;
cin >> n >> k;
if(n >= k) //如果n大于等于k 只能一步一步往回走
cout << n - k << endl;
else
printf("%d\n", bfs(n, k));
return 0;
}
D题:
天气冷了。
wy学姐玩起了卡牌游戏,她遇到了一个特殊关卡。
在这个关卡中,她只有数字为0或数字为5的卡牌可以打出伤害(把这些卡片上的数字排列成一排即为造成的伤害值)。
Of course,这个特殊的关卡有一个特殊的大BOSS,只有造成90的倍数的伤害值才有效果,否则BOSS将直接免疫伤害值。
天气越来越冷了。
wy学姐不想思考,于是她随机选择了幸运的你,来帮她解决这个问题——手中摸到的牌能打出的最大伤害数是多少?
注意:她可以不把卡牌全部用完。
Input
第一行是一个整数 n (1 ≤ n ≤ 103).
第二行是 n 个整数 a1, a2, ..., an (ai = 0 or ai = 5). 数 ai 即 i-th 卡片上的数字.
Output
输出一个数——造成的最大伤害(90的倍数)。
如果手中的卡牌无法生成90倍数的伤害值,则输出-1.
Examples
Input
4
5 0 5 0
Output
0
Input
11
5 5 5 5 5 5 5 5 0 5 5
Output
5555555550
思路:卡牌值只有0或5;
要是90的倍数,即打出5的个数为9的倍数。
利用桶 a[0],a[5]记录0或5的个数。
如果5的个数小于9,即打出0;如果也没有0,则输出-1;
如果a[5]>9&&a[0]>1,先输出a[5]/9个“555555555”,再输出a[0]个0;
#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<map>
#include<memory.h>
using namespace std;
typedef long long ll;
const int N = 205;
int main()
{
int n, n5 = 0, n0 = 0, x;
cin >> n;
for (int i = 0; i < n; ++i)
{
cin >> x;
if(x == 5)
n5++; //判断5的个数
else
n0++; //判断0的个数
}
if(n5/9 && n0)
{
int y = n5 / 9; //判断5的个数是9的多少倍
while(y)
{
cout << "555555555";
y--;
}
while(n0)
{
cout << "0";
n0--;
}
cout << endl;
}
else
if(n0)
cout << "0\n";
else
cout << "-1\n";
return 0;
}
E题
zks会长梦见一片充满宝藏的沙滩, 它是由若干正方形的块状土地组成的一个W*H矩形区域。zks会长决定挖出这片沙滩所有的宝藏,成为传说中的宝藏男孩!!!
不幸的是,在他挖第二块地时就触发了埋藏其中的地雷,他直接被从宿舍的床上炸醒。
他恍然大悟,原来这片沙滩上的每一块地,除了宝藏,还有可能是地雷!
故事没有就这样结束,第二天,他又做了相同的梦...
编写一个程序,计算出zks会长在被炸醒前可能挖到宝藏的最大数量。
Input
输入包含多组数据. 每组数据包含两个正整数W和H.
H表示列数,W表示行数. W和H不超过20.
每块地用字符表示如下:
'.' - 宝藏
'#' - 地雷
'@' - 起点(每组数据中只有一个,下面也有宝藏!)
输入 0 0 时程序结束
Output
对于每组数据,输出一个整数,即zks会长能挖到宝藏的最大数量。
Sample Input
6 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
11 9
.#.........
.#.#######.
.#.#.....#.
.#.#.###.#.
.#.#..@#.#.
.#.#####.#.
.#.......#.
.#########.
...........
11 6
..#..#..#..
..#..#..#..
..#..#..###
..#..#..#@.
..#..#..#..
..#..#..#..
7 7
..#.#..
..#.#..
###.###
...@...
###.###
..#.#..
..#.#..
0 0
Sample Output
45
59
6
13
思路:
- 首先找出@位置,记录。
- 向四周走有4个方案。
- 设变量ans.
- 尝试选一个方向走,判断这个方向是否可行(即未超界,未踩地雷),
- 若否,退回原位置,若行将这个方向可行将原位置设为#,ans++,以当前位置为起始位置重复以上操作直到4个方向都不行
- 输出ans.
E.
#include<iostream>
#include<cmath>
#include<map>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<string>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 505;
int a[N];
char graph[25][25];
int f[4] = {0, 0, +1, -1}, ff[4] = {+1, -1, 0, 0}, ans, w, h;
//f为x坐标的变化,ff为y坐标的变化
void dfs(int x, int y)
{
for(int i = 0; i < 4; ++i) // 上下左右四个方向依次尝试走
{
if(x+f[i] >= 0 && x+f[i] < h && y+ff[i] >= 0 && y+ff[i] < w && (graph[x+f[i]][y+ff[i]] == '.' ))
{ //如果没有走出地图,并且没有走到地图上
graph[x+f[i]][y+ff[i]] = '#'; //对于已经走到的地方,把他变成地雷(即不走回头路)
ans++;
dfs(x+f[i], y+ff[i]); //以走到的位置为起始位置再次尝试
}
}
}
int main()
{
int s, t;
while(cin >> w >> h && (w+h))
{
ans = 1;
for(int i = 0; i < h; ++i)
for(int j = 0; j < w; ++j)
{
cin >> graph[i][j];
if(graph[i][j] == '@')
s = i, t = j; //记录起始位置
}
dfs(s, t);
cout << ans << endl;
}
return 0;
}
G题:
协会正在举行一场对外的加时赛,在这场比赛中有n个小队,依次从1到n进行编号。
每一轮比赛后剩下小队的ID会重新按照顺序依次编号,然后按以下顺序进行比赛:第一队和第二队比,第三队和第四队比,依此类推。
可以保证在每一轮比赛中都有偶数个队。
每场比赛的获胜者晋级下一轮,失败者被淘汰出局,没有平局。
在最后一轮比赛中,只剩下两支小队,这一轮被称为决赛,获胜者被称作冠军。
大家都希望lh学长带领的小队和hz学长带领的小队进入决赛。
不幸的是,球队ID已经被确定了,lh学长和hz学长可能不会在决赛中相遇,因为如果他们足够强大,他们将在更早的阶段相遇。
请你预测一下,lh学长所在的ID为a和hz学长所在的ID为b的小队将会在哪一轮中碰面。
注意:lh学长的小队和hz学长的小队是所有小队中最强的存在!!!
Input
唯一的行包含三个整数n,a和b (2≤n≤256,1≤a,b≤n) 分别为参加比赛的小队总数,lh学长所带领的小队编号,hz学长所带领的小队编号。
可以保证,在每一轮比赛中,都有偶数个队晋级,并且a和b不相等。
Output
如果lh学长和hz学长可以在决赛中相遇,则输出唯一一行“Final!”(没有引号)
否则输出lh学长和hz学长相遇的轮数。
轮数是从1开始累计的。
Examples
Input
4 1 2
Output
1
Input
8 2 6
Output
Final!
Input
8 7 5
Output
2
思路:规律题
- 2 (-1)/2+=1 (2-)/2+=1
- 4 (3-1)/+1=2 (4-1)/+1=2
5 6``````````;
定义a,b;将lh学长所带领的小队编号,hz学长所带领的小队编号输入a,b;
利用公式(n-1)/2+1,当((a-1)/2+1)=((b-1)/2+1)即相遇。记录公式利用次数即相遇轮次。
计算比赛总共需要次数,与相遇轮次一致即输出Final!,若不是输出轮次。
#include<iostream>
using namespace std;
int main()
{
int n, a, b, i, j;
cin >> n >> a >> b;
for (j = 1;; j++)
{
n = n / 2;
if (n == 1) break;
}
for (i = 1;; i++)
{
if ((a - 1) / 2 + 1== (b - 1) / 2 + 1) break;
a = (a-1) / 2 + 1;
b = (b-1) / 2 + 1;
}
if (i == j) cout << "Final!" << endl;
else cout << i << endl;
return 0;
}
H题:
z-sort过的数组是这样的
- ai ≥ ai - 1 (i是偶数)
- ai ≤ ai - 1 (i是奇数,且i大于1)
[1,2,1,2] 和[1,1,1,1] 是z-sort过的 但是[1,2,3,4] 不是
lh学长将会给你一个数组,希望你可以帮他弄成z-sort过的,他将会奖励你他的小心心❤~~~
Input
第一行一个整数n (1 ≤ n ≤ 1000)
第二行n 个整数 ai (1 ≤ ai ≤ 109)
代表这个数组
Output
如果可以变成z-sort过的数组,就输出数组,否则输出 "Impossible".
Examples
Input
4
1 2 2 1
Output
1 2 1 2
Input
5
1 3 2 2 5
Output
1 5 2 3 2
思路:
- 将给出的n个数输入a[ ],并升序排序。
- 将前(n-1)/2+1个数放入b[ ]的 奇数位。
- 将后面的数放入b[ ]的偶数位
- 再进行判断偶数位的值是否大于等于相邻的奇数位的值。
- 是即输出b[ ],否输出Impossible。
#include<iostream>
#include<cmath>
#include<map>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<string>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 1005;
int a[N], b[N];
int main()
{
int n, cnt = 0;
cin >> n;
for(int i = 0; i < n; ++i)
cin >> a[i];
sort(a, a+n);
for(int i = 0; i < n; i += 2) //奇数位上放小的数
b[i] = a[cnt++];
for(int i = 1; i < n; i += 2) //偶数位上放大的数(即尽可能使偶数位的数大于俩边的数)
b[i] = a[cnt++];
int i;
for(i = 1; i < n; ++i)
{
if((i % 2 && b[i] < b[i-1])||(!(i % 2) && b[i] > b[i-1])) //如果不满足条件,则不是想要的数组
break;
}
if(i < n) //i不到n说明经历了break 即数组不满足条件
cout << "Impossible";
else
for(int j = 0; j < n; ++j)
cout << b[j] << " ";
cout << endl;
return 0;
}