郭式树
Problem Description
郭橐驼,不知始何名。病偻,隆然伏行,有类橐驼者,故乡人号之驼。驼闻之,曰:“甚善。名我固当。”因舍其名,亦自谓橐驼云。其乡曰丰乐乡,在长安西。驼业种树,凡长安豪富人为观游及卖果者,皆争迎取养。视驼所种树,或移徙,无不活;且硕茂,蚤实以蕃。他植者虽窥伺效慕,莫能如也。 有问之,对曰:“橐驼非能使木寿且孳也,以能顺木之天,以致其性焉尔。凡植木之性,其本欲舒,其培欲平,其土欲故,其筑欲密。既然已,勿动勿虑,去不复顾。其莳也若子,其置也若弃,则其天者全,而其性得矣。故吾不害其长而已,非有能硕而茂之也。不抑耗其实而已,非有能蚤而蕃之也。他植者则不然:根拳而土易。其培之也,若不过焉则不及。苟有能反是者,则又爱之太殷,忧之太勤。旦视而暮抚,已去而复顾;甚者爪其肤以验其生枯,摇其本以观其疏密,而木之性日以离矣。虽曰爱之,其实害之;虽曰忧之,其实仇之,故不我若也,吾又何能为哉?”
相传郭橐驼又在种树了,他沿着一条笔直的马路种了3棵树A,B,C。
不过忘记了ABC从左到右的顺序,他只知道B在A的右方 x 步处(如果 x 为负则B在A的左方 -x 步处),C在A的右方 y 步处(如果 y 为负责C在A左方 -y 步处)。
他想知道BC距离多少步(答案一定为正数且不为0)。
因为他种的树太多了,他只知道 |x|, |y| (取绝对值, |1| = 1, |-2| = 2) ≤ 4611686018427387904
Input
第一行是数据组数T(T ≤ 100000)
每组数据两个整数 x , y (-4611686018427387904 ≤ x, y ≤ 4611686018427387904)
Output
Sample Input
2 1 2 4611686018427387904 -4611686018427387904
Sample Output
1 9223372036854775808
Source
Manager
来自某训练。。注意处理好-9223372036854775808的情况就好了
AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define LL long long
#define ULL unsigned long long
using namespace std;
int main() {
int T;
LL x, y;
//printf("%lld", 0x7fffffffffffffff);
scanf("%d", &T);
while(T--) {
scanf("%lld %lld", &x, &y);
if(x < y) swap(x, y);
LL t = x - y;
if(t == -9223372036854775808)
printf("9223372036854775808\n");
else if(t < 0) printf("%lld\n", -t);
else printf("%lld\n", t);
}
return 0;
}
面面数
Problem Description
DS 看见过这么一个题目:
求在三维世界中,经过一个公共点的 n 个平面(但任意三个平面不过同一直线)把空间分成的块数
DS发现整个平面被分成了 N 部分(N ≤ 2000000000),那么最少需要用多少个平面呢?
致歉:
请 if (n == 0) cout << 1 << endl; .... Sorry
Input
第一行一个整数代表数据的组数 T (T ≤ 10000)
每组数据一个整数 N (1 ≤ N ≤ 2000000000)
Output
Sample Input
5 1 2 3 4 100
Sample Output
0 1 2 2 11
Source
Manager
有规律:a[i] = i * i - i + 2;
证明:(1)、a(0) = 1, a(1) = 2, a(2) = 4, a(3) = 8
(2)、当n>3时,每增加一个面,这面就要与前面n-1个面都相交,因为过同一点,两平面如果有一个公共点就有一条公共直线,这样就会把前面平面划分的空间一分为二,a(n) - a(n-1)=2 * (n-1),然后累加得a(n)=n^2-n+2
AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long
using namespace std;
LL a[47000] = {1, 2, 4, 8};
void init() {
for(LL i = 4; i < 47000; i++)
a[i] = i * i - i + 2;
}
int main() {
init();
//for(int i = 46001; i < 46050; i++) printf("%d\n", a[i]);
int T, N;
scanf("%d", &T);
while(T--) {
scanf("%d", &N);
if(N == 0) {
printf("1\n");
continue;
}
int t = 0;
while(a[t] < N) t++;
printf("%d\n", t);
}
return 0;
}
圆有点挤
Problem Description
Input
输入的第一行是一个整数,为数据的组数t(t<=1000)。
每组数据占一行,包括4个数A,B,R1,R2,均为不超过1e4的正整数。
Output
Sample Input
2 10 10 1 1 10 10 4 4
Sample Output
YES NO
Source
Manager
注意斜着放就好了
AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int main() {
double A, B, r1, r2;
int T;
scanf("%d", &T);
while(T--) {
scanf("%lf %lf %lf %lf", &A, &B, &r1, &r2);
if(A < B) swap(A, B);
if( (2 * r1 <= A && 2 * r1 <= B && 2 * r2 <= A && 2 * r2 <= B)) {
if( (r1 + r2 + sqrt(2.0*r1*r1) + sqrt(2.0*r2*r2)) <= sqrt(A * A + B * B) ) {
printf("YES\n");
}
else {
printf("NO\n");
}
}
else {
printf("NO\n");
}
}
return 0;
}
瑶瑶的第K大
Problem Description
一天,萌萌的妹子--瑶瑶(tsyao)很无聊,就来找你玩。可是你们都不知道玩什么。。。尴尬了一阵子,机智的瑶瑶就提议:“这样吧,你说N个整数xi,然后在随意说一个数字k,我能够快速地说出这些数字里面第 k 大的数字。”
Input
第1行 两个整数N, K以空格隔开;
第2行 有N个整数(可出现相同数字,均为随机生成),同样以空格隔开。
0 < n ≤ 5*10^6 , 0 < k ≤ n
1 ≤ xi ≤ 10^8
Output
Sample Input
5 2 5 4 1 3 1
Sample Output
4
Hint
Source
Manager
思路:直接调用sort会超时,这就考验你对快排的熟练程度了,在每次递归调用都增加两层边界,具体看代码;
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int a[5000005];
int N, K;
void Qsort(int a[],int low,int high)
{
if(low > N - K) return;
if(high < N - K) return;
if(low >= high) return;
int first = low;
int last = high;
int key = a[first];
while(first < last)
{
while(first < last && a[last] >= key) last--;
a[first] = a[last];
while(first < last && a[first] <= key) ++first;
a[last] = a[first];
}
a[first] = key;
Qsort(a, low, first - 1);
Qsort(a, first + 1, high);
}
int main() {
while(scanf("%d %d", &N, &K) != EOF) {
for(int i = 0; i < N; i++) {
scanf("%d", &a[i]);
}
Qsort(a, 0, N - 1);
printf("%d\n", a[N - K]);
}
return(0);
}