问题 A: 又是斐波那契数列??
时间限制: 1 Sec 内存限制: 128 MB
题目描述
大家都知道斐波那契数列吧?斐波那契数列的定义是这样的: f0 = 0; f1 = 1; fi = fi-1 + fi-2
现在给你一个数x,聪明的你一定知道这是斐波那契数列中的第几项。
(数据保证x一定有对应的项y,且 0 <= y < 1e4)
输入
第一行一个整数T,表示测试组数。
之后的T行,每行一个数x
输出
对于每个测试数据,输出一行表示数x是第几项
样例输入
2
2
5
样例输出
3
5
解题思路
因数组要开到9999,发现数太大,换个思路,就是先对数列的值一 一取模,并将对应的位置记录下来,接下来便是对输入的数化为字符串形式,进行高精度取模(大数取模);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii; const int N = (int) 100000 + 11; const int M = (int) 1e6 + 11; const int mod6 = (int) 1e9 + 7; const int INF = (int) 0x3f3f3f3f; ull f[N]={0,1}; map<ull, int> mp; int main(){ mp[1] = 1; mp[0] = 0; for(int i = 2; i < N; i++){ f[i] = (f[i-1] %mod+ f[i-2]%mod)%mod; mp[f[i]] = i; } int T; cin>>T; while(T--){ string s; cin>>s; ull ans=0; for(int i = 0; s[i]; i++) ans = (ans * 10 + s[i] - '0')%mod; cout<<mp[ans]<<"\n"; } return 0; } |
问题 B: Monotonic interval
时间限制: 1 Sec 内存限制: 128 MB
题目描述
设 f:P→Qf:P→Q 是在两个带有偏序 ≤≤ 的集合 PP 和 QQ 之间的函数。在微积分中,它们是带有平常次序的实数集的子集之间的函数,但是定义仍保持同更一般的序理论定义一样。
函数 ff 是单调的,如果只要 x≤yx≤y,则 f(x)≤f(y)f(x)≤f(y)。因此单调函数保持次序关系。
Neo 在研究某个一元函数 f(x)f(x) 的单调性,由于该函数太复杂了,没办法直接求导。但是能很容易的知道 f(x)f(x) 在 x1,x2,…,xkx1,x2,…,xk 的取值为 f(x1),f(x2),…,f(xk)f(x1),f(x2),…,f(xk) 。现在需要判断 f(x)f(x) 在区间 [l,r][l,r] 是否单调。
若 f(x)f(x) 在区间 [l,r][l,r] 可能单调,请输出 “Possible”
若 f(x)f(x) 在区间 [l,r][l,r] 不可能单调,请输出 “Impossible”
输入
第一行两个整数 k,qk,q
第二行 kk 个整数,第 ii 个值代表 xixi
第三行 kk 个整数,第 ii 个值代表 f(xi)f(xi)
接下来 qq 行,每行两个整数 l,rl,r
对于所有的输入 0<k,q≤1050<k,q≤105,其他值的绝对值均不超过 109109
数据保证: ∀i≠j∀i≠j 都有 xi≠xjxi≠xj
输出
请输出 qq 行答案。
样例输入
5 3 1 2 3 4 5 5 4 3 4 5 1 3 2 4 3 5
样例输出
Possible Impossible Possible
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
#include<bits/stdc++.h> using namespace std; const int MAXN = (int)1e5+ 5; typedef pair<int, int> pii; map<int, int> mp; pii dat[MAXN]; int u[MAXN], d[MAXN], ip[MAXN]; int main() { int k, q; while(scanf("%d%d", &k, &q) != EOF) { memset(u, 0x00, sizeof(u)); memset(d, 0x00, sizeof(d)); for(int i = 1; i <= k; ++i) { scanf("%d", &dat[i].first); } for(int i = 1; i <= k; ++i) { scanf("%d", &dat[i].second); } sort(dat + 1, dat + k + 1); // 按 first 进行从小到大排序 for(int i = 2; i <= k; ++i) { // 如果是非递减的,则 u[i] 的值不会发生改变,即 u[i] == u[i-1] // 如果是非递增的,则 d[i] 的值不会发生改变 ,即 d[i]==d[i-1] u[i] += u[i - 1]; d[i] += d[i - 1]; if(dat[i].second < dat[i - 1].second) ++u[i]; if(dat[i].second > dat[i - 1].second) ++d[i]; } for(int i = 1; i <= k; ++i) ip[i] = dat[i].first; u[k + 1] = u[k]; d[k + 1] = d[k]; for(int i = 0; i < q; ++i) { int l, r; scanf("%d%d", &l, &r); int ll = lower_bound(ip + 1, ip + 1 + k, l) - ip; int rr = upper_bound(ip + 1, ip + 1 + k, r) - ip - 1; // 若 u[rr] == u[ll] ,说明在此区间内 非递减 // 若 d[rr] == d[ll] ,说明在此区间内 非递增 // 若 rr <= ll 说明 l和 r 在一区间的内部,有可能 单调 puts(rr <= ll || u[rr] == u[ll] || d[rr] == d[ll] ? "Possible" : "Impossible"); } } return 0; } |
问题 C: Simplest
时间限制: 1 Sec 内存限制: 128 MB
题目描述
给你一段由数字0 - 9组成的字符串,请你输出它的最简自然数形式
输入
第一行一个T,表示T组测试数据.(1 ≤ T ≤ 100)
每一组数据占一行,每一行一串字符 S. (1 ≤ strlen(S) ≤ 100000)
输出
输出字符串对应的最简自然数形式
样例输入
2 2018722 02018722
样例输出
2018722 2018722
注意 :
当s 为 00000 时,输出为 0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#include <iostream> #include<algorithm> #include<cstring> #include<string> using namespace std; int main() { int t,k,i; string s; cin >> t; while(t--){ cin >> s; k=0; for(i=0;i<s.length();i++){ if(s[i]!='0')break; k++; } if(k==s.length())cout<<0 << endl; else{ s=s.substr(k,s.length()); cout<< s<<endl; } } } |
问题 D: zz’s math problem Ⅰ
时间限制: 3 Sec 内存限制: 32 MB
题目描述
zz很喜欢数学,但是他又是一个数学渣,我们称这种生物叫做学渣,
zz又碰到了一个数学小问题,定义一个函数P (x)
例如:P (123) = 1! ∗ 2! ∗ 3! 现在需要找到的就是最大的大于等于x大的数z的函数值和x相等,
即P (z) = P (x) 当然z这个数不能包含1或者0
还请输出最大的符合要求数z(不一定比x大)
输入
第1行输入T (1 ≤ T ≤ 20)组数据
第2行输入n(1 ≤ n ≤ 100),表示x的数字个数
第3行输入正整数 x
输出
输出最大的z(数据保证x内含大于1的数,所以z必定有解)
样例输入
2 4 1234 3 555
样例输出
33222 555
提示
第一个样例f(1234) = 1! ∗ 2! ∗ 3! ∗ 4! = 288 = f(33222)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
#include <iostream> #include <vector> #include <string> #include <algorithm> using namespace std; #define pb push_back int main() { int T, n, x; cin >> T; while(T--) { vector<int> v,vv; string s; cin >> n; cin >> s; for(int i = 0; i < n; ++i) { x = s[i]-'0'; if(x == 9) { v.pb(7); v.pb(3); v.pb(3); v.pb(2); } else if(x == 8) { v.pb(7); v.pb(2); v.pb(2); v.pb(2); } else if(x == 6) { v.pb(5); v.pb(3); } else if(x == 4) { v.pb(3); v.pb(2); v.pb(2); } else if(x!=1&&x!=0) v.pb(x); } sort(v.begin(), v.end(), greater<int>()); for(int i = 0; i < v.size(); ++i) { cout << v[i]; } cout << "\n"; } return 0; } |
问题 E: zz’s math problem Ⅱ
时间限制: 3 Sec 内存限制: 32 MB
题目描述
zz作为一个数学盲也认为这个数学题真的很简单, 学弟学妹们终于可以顺利签到了qwq
给出NN个正整数a1,a2,...,aNa1,a2,...,aN,
我们寻找一个这个表达式的最大的值 f(m)=(m mod a1)+(m mod a2)+...+(m mod aN)f(m)=(m mod a1)+(m mod a2)+...+(m mod aN)
modmod的意思即为A/BA/B的余数
输入
第11行输入T(1≤T≤20)T(1≤T≤20)组数据
第22行输入N(1≤N≤1e3)N(1≤N≤1e3)
第33行输入nn个数字ai(1≤ai≤1e5)ai(1≤ai≤1e5),
输出
输出 ff 的最大值
样例输入
1 3 3 4 6
样例输出
10
提示
f(11)=(11 mod 3)+(11 mod 4)+(11 mod 6)f(11)=(11 mod 3)+(11 mod 4)+(11 mod 6)的值1010就是函数的最大值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include <bits/stdc++.h> using namespace std; #define pb push_back #define LL long long int main() { int T, x; cin >> T; while(T--) { int n; int ans = 0; cin >> n; for(int i = 1; i <= n; ++i) { cin >> x; ans += x-1; } cout << ans << "\n"; } return 0; } |
问题 F: Operation on sequence
时间限制: 1 Sec 内存限制: 512 MB
题目描述
一组下标从11开始的数组ss,进行qq次操作:
考虑两种操作:
11 rr,将子序列a[1]a[1] 到 a[r]a[r] 从小到大排序
22 rr,将子序列a[1]a[1] 到 a[r]a[r] 从大到小排序
输入
第一行输入T组数据 T(1≤T≤10)T(1≤T≤10)
第一行输入两个数字 n,q(1≤n,q≤1e4)n,q(1≤n,q≤1e4)
第二行包含nn个整数 ai(−1e9≤ai≤1e9)ai(−1e9≤ai≤1e9) — 初始序列
然后qq行表示mm个操作. 第ii行包含两个整数 op(1≤op≤2)op(1≤op≤2), r(1≤r≤n)r(1≤r≤n)
输出
输出nn个数字,即数组被操作qq次改变后的数组
注意,我们要输出的是最终改变后的结果
样例输入
2 3 1 1 2 3 2 2 4 2 1 2 4 3 2 3 1 2
样例输出
2 1 3 2 4 1 3
提示
在第二组样例中初始序列是: 1 2 4 3.
执行第一次操作后的序列是: 4 2 1 3. 执行第二次操作后的序列是: 2 4 1 3.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
#include <bits/stdc++.h> using namespace std; const int MAXN = 2e5+10; int n,m; int x[MAXN]; // 整数数据 int px[MAXN],uu,vv; int ans[MAXN]; int s1[MAXN],s2[MAXN],tt=1; int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int T; cin >> T; while(T--) { memset(px, 0, sizeof px); memset(ans, 0, sizeof ans); memset(s2, 0, sizeof s2); memset(s1, 0, sizeof s1); scanf("%d%d",&n,&m); int a,b,c,i,j,k; for(a=1;a<=n;a++) scanf("%d",&x[a]); s2[0]=19260817; for(a=1;a<=m;a++) { scanf("%d%d",&i,&j); while(j>=s2[tt-1]) tt--; s2[tt]=j;s1[tt]=i;tt++; } k=s2[1]; for(a=1+k;a<=n;a++) ans[a]=x[a]; for(a=1;a<=k;a++) px[a]=x[a]; sort(px+1,px+k+1); uu=1;vv=k; s2[tt]=0; for(a=1;a<tt;a++) { if(s1[a]==1) { for(b=s2[a];b>s2[a+1];b--) ans[b]=px[vv--]; } else { for(b=s2[a];b>s2[a+1];b--) ans[b]=px[uu++]; } } for(a=1;a<n;a++) printf("%d ",ans[a]); printf("%d\n",ans[n]); } return 0; } |
问题 G: Operation on sequence
时间限制: 1 Sec 内存限制: 512 MB
题目描述
真·签到题
输入一个表达式AA opop BB opop操作为′+′,′−′,′∗′′+′,′−′,′∗′ ,A,BA,B为整数
输入
第一行输入T 组数据T(1≤T≤1e2)T(1≤T≤1e2)
第二行输入AA opop BB (−1e9≤A,B≤1e9)(−1e9≤A,B≤1e9) — 初始序列
输出
输出表达式结果并换行即可
样例输入
1
1 + 1
样例输出
2
|
|
问题 H: 又是划分问题
时间限制: 1 Sec 内存限制: 512 MB
题目描述
给你一个正整数n,将其划分,要求划分成的数必须是2的幂,有多少种划分方法??
结果可能很大,我们输出对1e9+7取模的结果
输入
一个正整数n,代表要划分的数;
1<=n<=1e71<=n<=1e7
输出
输出可划分的方法数
样例输入
15
67
样例输出
26
2030
提示
当n=6时,我们可以将其划分为
1 1 1 1 1 1
1 1 1 1 2
1 1 2 2
2 2 2
1 1 4
2 4
这6种划分方法
|
|
问题 I: 凸包与椭圆
时间限制: 3 Sec 内存限制: 128 MB
题目描述
在数学中,椭圆是围绕两个焦点的平面中的曲线,使得对于曲线上的每个点,到两个焦点的距离之和是恒定的。因此,它是圆的概括,其是具有两个焦点在相同位置处的特殊类型的椭圆。椭圆的形状(如何“伸长”)由其偏心度表示,对于椭圆可以是从0(圆的极限情况)到任意接近但小于1的任何数字。
判断多个点组成的凸包是否与椭圆(x−x0)2a2+(y−y0)2b2=1(x−x0)2a2+(y−y0)2b2=1相交;若是,则输出Yes,否则输出No。凸包就是把给定点包围在内部的、面积最小的凸多边形。
输入
包含T组测试数据,对于每组测试数据,先输入一个整数n;接下来一行输入x0,y0,a,bx0,y0,a,b;接下来一行输入n个整数,代表n个点的横坐标;接下来一行输入n个整数,代表n个点的纵坐标;
(x0,y0)(x0,y0)代表椭圆的中心点。(a,b≠0),(3≤n≤105)(a,b≠0),(3≤n≤105)
输出
如果多个点组成的凸包与椭圆相交(误差保证在10−1010−10),则输出Yes,否则输出No
样例输入
1 3 0 0 5 4 5 5 10 1 -1 10
样例输出
Yes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; struct Point{ double x,y; Point(double x=0,double y=0):x(x),y(y){ } }; typedef Point Vector; Vector operator + (Vector A,Vector B){ return Vector(A.x+B.x,A.y+B.y); } Vector operator - (Vector A,Vector B){ return Vector(A.x-B.x,A.y-B.y); } const double eps=1e-10; int dcmp(double x){ if(fabs(x)<eps) return 0; else return x<0?-1:1; } Point p[100005],ch[100005]; bool cmp(Point A,Point B){ if(A.x==B.x) return A.y<B.y; else return A.x<B.x; } double det(Point A,Point B){ return A.x*B.y-A.y*B.x; } int ConvexHull(Point* p,int n,Point* ch){ sort(p,p+n,cmp); int m=0; for(int i=0;i<n;i++){ while(m>1&&det(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--; ch[m++]=p[i]; } int k=m; for(int i=n-2;i>=0;i--){ while(m>k&&det(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--; ch[m++]=p[i]; } if(n>1) m--; return m; } double xx,yy,a,b; bool check(Point A, Point B) { if(dcmp(A.x - B.x) == 0) { double delta = b * b - b * b * A.x * A.x / a / a; if(delta < -eps) return false; double y_1 = -sqrt(fabs(delta)); double y_2 = sqrt(fabs(delta)); return (dcmp(max(A.y, B.y) - y_2) >= 0 && dcmp(min(A.y, B.y) - y_2) <= 0 || (dcmp(min(A.y, B.y) - y_1) <= 0 && dcmp(max(A.y, B.y) - y_1) >= 0)); } double k = (A.x - B.x) ? (A.y - B.y) / (A.x - B.x) : 1e100; double g = -k * A.x + A.y; double _a = b * b + a * a * k * k; double _b = 2 * a * a * g * k; double _c = a * a * (g * g - b * b); double delta = _b * _b - 4 * _a * _c; if(delta < -eps) return false; double x_1 = (-_b - sqrt(fabs(delta))) / _a / 2.0; double x_2 = (-_b + sqrt(fabs(delta))) / _a / 2.0; return (dcmp(max(A.x, B.x) - x_2) >= 0 && dcmp(min(A.x, B.x) - x_2) <= 0 || (dcmp(min(A.x, B.x) - x_1) <= 0 && dcmp(max(A.x, B.x) - x_1) >= 0)); } int main() { int T,n; scanf("%d",&T); while(T--){ scanf("%d",&n); scanf("%lf%lf%lf%lf",&xx,&yy,&a,&b); for(int i=0;i<n;i++){ scanf("%lf",&p[i].x); p[i].x-=xx; } for(int i=0;i<n;i++){ scanf("%lf",&p[i].y); p[i].y-=yy; } int m=ConvexHull(p,n,ch); int flag=0; for(int i=0;i<m;i++){ if(check(ch[i],ch[(i+1)%m])){ flag=1; break; } } if(flag) printf("Yes\n"); else printf("No\n"); } return 0; } |
问题 J: 台阶问题
时间限制: 1 Sec 内存限制: 128 MB
题目描述
有 N 级的台阶,你一开始在底部,每次可以向上迈最多 K 级台阶(最少 1 级),问到达第 N 级台阶有多少种不同方式。
输入
多组输入,两个正整数N(N ≤ 1000),K(K ≤ 100)。
输出
一个正整数,为不同方式数,由于答案可能很大,你需要输出 ans mod 100003 后的结果。
样例输入
5 2
样例输出
8
|
|
问题 K: 括号括号
时间限制: 3 Sec 内存限制: 128 MB
题目描述
小明今年上大学,在大学里发现有很多同学都女朋友,两人整天都在一起腻歪,小明看到后感觉很孤单,现在,给你一行括号序列,你来判断一下其中的括号是否配对。
输入
多组输入,每一组第一行输入一个数T(0<<N≤≤100),表示有T组测试数据。后面的T行输入多组输入数据,每组输入数据都是一个字符串S(S的长度小于10000,且S不是空串),测试数据组数少于5组。数据保证S中只含有"[", "]", "(", ")" 四种字符
输出
每组输入数据的输出占一行,如果该字符串中所含的括号是配对的,则输出Yes,如果不配对则输出No。
样例输入
3
[(])
(])
([[]()])
样例输出
No
No
Yes
|
|