--12月月赛题解--
来源:互联网 发布:csol控制台优化 编辑:程序博客网 时间:2024/04/30 10:39
12月月赛题解
问题 A: 求区间最大值
题目描述
给你一个长度为n的序列{a_1,a_2…a_n},下标从1到n,Q个询问,每次询问给出一个L和R,你需要输出最大的a_i,(L<=i<=R)
输入
单组数据
第一行给出n,(n<=1e6)
第二行有n个数代表{a_1,a_2…a_n},(a_i不超过int范围)
第三行给出q,代表有q个询问,(q<=1e6)
接下来q行每行给出两个数字代表L,R,(1<=L<=R<=n)
输出
对于每个询问,输出最大值
样例输入
4
2 1 3 4
2
1 2
1 4
样例输出
2
4
题解
线段树裸题
#include <cstdio>#include <algorithm>using namespace std;#define lson l,(l+r)/2,rt<<1#define rson (l+r)/2+1,r,rt<<1|1int a[1000000];int T[1000001*4];inline void build(int l,int r,int rt){ if(l==r){T[rt]=a[l];return;} build(lson); build(rson); T[rt]=max(T[rt<<1],T[rt<<1|1]);}inline int query(int l,int r,int rt,int L,int R){ if(l>=L && r<=R)return T[rt]; int ret=-1; if((l+r)/2>=L)ret=max(ret,query(lson,L,R)); if((l+r)/2+1<=R)ret=max(ret,query(rson,L,R)); return ret;}int main(){ //freopen("in","r",stdin); //freopen("out1","w",stdout); int n; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } build(1,n,1); int q; scanf("%d",&q); while(q--){ int l, r; scanf("%d %d",&l,&r); printf("%d\n",query(1,n,1,l,r)); } return 0;}
问题 B: 服务器
题目描述
Bob的实验室中有n台服务器可以用来处理任务.每台服务器有一个独特的id–是一个从1到n的整数.
现在有q个任务要来,其中第i个任务的定义包含三个整数: ti –
这个任务到来的时刻(以秒为单位), ki –这个任务要 ki台服务器共同处理, di –处理这个任务时每台服务器所需要的时间.保证输入的所有ti是不同的.
为了完成第i个任务,你需要ki 台服务器在 ti秒没有被占用.一旦一台服务器开始执行任务的时候,他在接下来的di 秒将处于忙碌状态,即他将于ti, ti + 1, …, ti + di - 1秒处于忙碌状态.为了完成第i个任务,将用到ti时刻没有被占用的 ki 台id最小的服务器.如果 ti时刻没有被占用的服务器不足 ki ,那么这个任务将被忽略.
写一个程序判断哪些任务将被执行,那些任务将被忽略.
输入
输入包含一组数据
第一行包含两个整数n和q (1 ≤ n ≤ 100, 1 ≤ q ≤ 105),表示服务器的数量和任务的数量
接下来的q行,每行包含三个整数 ti, kiand di (1 ≤ ti ≤ 106, 1 ≤ ki ≤ n, 1 ≤ di ≤ 1000)表示第i个任务到来的时刻(秒),需要多少台服务器来运行以及每台服务运行他所需要的时间.任务将以字典序的顺序给出,并且每个任务的到来时间都不相同.
输出
打印q行,如果第i个任务将被服务器执行,在第i行打印运行第i个任务的服务器的id之和,否则打印-1.
样例输入
4 3
1 3 2
2 2 1
3 4 3
样例输出
6
-1
10
题解
按照描述模拟就好了
#include<iostream>#include<cstdio>#include<algorithm>#include<vector>#include<map>#include<set>#include<queue>#include<stack>#include<cstring>#include<string>using namespace std;const int maxsize = (int)(2e5 + 7);struct node{ int t,k,d; int id; bool operator<(node b) { return t<b.t; }};node D[maxsize];//100*10^5int B[107];int BB[107];int Ans[maxsize];//sumint main(){ int n,q; cin>>n>>q; for(int i=0;i<q;i++) { scanf("%d%d%d",&D[i].t,&D[i].k,&D[i].d); D[i].id = i; } //sort(D,D+q); memset(Ans,-1,sizeof(Ans)); for(int i=0;i<q;i++) { int bbcnt = 0; int sum = 0; for(int j=0;j<n&&bbcnt<D[i].k;j++) { if(B[j]<=D[i].t) { BB[bbcnt++] = j; sum+=j+1; } } if(bbcnt==D[i].k) { for(int j=0;j<bbcnt;j++) { B[BB[j]] = D[i].t+D[i].d; } Ans[D[i].id] = sum; } } for(int i=0;i<q;i++) { printf("%d\n",Ans[i]); } return 0;}
问题 C: 机器人
题目描述
有编号1-n的n个格子,机器人从1号格子顺序向后走,一直走到n号格子,并需要从n号格子走出去。机器人有一个初始能量,每个格子对应一个整数A[i],表示这个格子的能量值。如果A[i] > 0,机器人走到这个格子能够获取A[i]个能量,如果A[i] < 0,走到这个格子需要消耗相应的能量,如果机器人的能量 < 0,就无法继续前进了。问机器人最少需要有多少初始能量,才能完成整个旅程。
例如:n = 5。{1,-2,-1,3,4} 最少需要2个初始能量,才能从1号走到5号格子。途中的能量变化如下3 1 0 3 7。
1e9>=n>=1
-1e5<=A[i]<=1e5
输入
给定一个n,接下来n行,每行一个数字,第i行的数字是A[i],表示这个格子能获取的能量
输出
输出结果为一个数字,代表机器人最少需要有多少的初始能量
样例输入
5
1
-2
-1
3
4
样例输出
2
题解
遍历一遍数组内所有元素,用on的时间复杂度可以预处理处数组里所有元素的前缀和(sum[i] = sum[i-1]+a[i]),再遍历一次sum数组,sum数组中的最小值的就是答案(注意要输出这个数的相反数)
#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>using namespace std;int main(void){ int i,j,n; long long ans=2100000000,a[100100],sum=0; cin>>n; for(i=0;i<n;i++) { cin>>a[i]; if(i==0) sum=a[i]; else sum=a[i]+sum; ans=min(ans,sum); } if(ans>=0) printf("0\n"); else printf("%lld\n",0-ans); return 0;}
问题 D: 最后一个是谁?
题目描述
有n个人围成一圈,顺序排号。从第一个人开始报数(第一个报1,第二个报2……),凡报到m的人退出圈子(下一个人从1开始报),问最后留下的是原来第几号的那位。
输入
多组测试数据 t;
第一行输入t,1<=t<=10.
接下t行,每行两个整数,n,m 1<=n<=1000,1<=m<=1000.
输出
输出t行,每行一个整数。
样例输入
2
468 335
501 170
样例输出
88
393
题解
模拟,循环的实现就是迭代i对当前剩余人数取模,直到剩余人数为1时停止。
#include<bits/stdc++.h>using namespace std;int main(){ //freopen("samplein_5.txt", "r", stdin); //freopen("sampleout_5.txt", "w", stdout); int t; scanf("%d",&t); while(t--) { int i; int n,m; int k,j; scanf("%d%d",&n,&m); int *Array=new int[n]; for(i=0;i<n;i++) { Array[i]=i+1; } i=1; k=0; for(j=0;k<n-1;j=++j%n) { if(Array[j]!=0) { if(i==m) { k++; Array[j]=0; i=1; } else { i++; } } } for(i=0;i<n;i++) { if(Array[i]!=0) { printf("%d\n",i+1); break; } } } return 0;}
问题 E: 三角
题目描述
将1,2,······,9共9个数排成下列形态的三角形。
a
b c
d e
f g h i
其中:a~i分别表示1,2,······,9中的一个数字,并要求同时满足下列条件:
(1)a < f < i;
(2)b < d, g < h, c < e
(3)a+b+d+f=f+g+h+i=i+e+c+a=P
输入
边长之和P
输出
所有满足上述条件的三角形的个数以及其中的一种方案。
若有多种方案输出字典序最小的那种。若无解输出NO。
样例输入
21
样例输出
4
3
2 4
9 6
7 1 5 8
题解
a+b+d+f=P,枚举a,b,d,根据f=P-a-b-d计算出f
#include <iostream>#include <cstdio>#include <cstring>using namespace std;bool v[10]; int p,a[10],b[10],ans=0; bool work(int step,int x) { if(v[x])return 0; if(step==2 || step==3 || step==7)return 1; if(step==4)return x>a[2]; if(step==5)return x>a[3]; if(step==6)return (x>a[1])&&(a[1]+a[2]+a[4]+x==p); if(step==8)return x>a[7]; if(step==9)return (x>a[6])&&(a[6]+a[7]+a[8]+x==p) && (a[1]+a[3]+a[5]+x==p); return 1;} void dfs(int step){ int i,j,k; if(step>=9) { ans++; if(ans==1) for(i=1;i<=9;i++) b[i]=a[i]; return; } for(i=1;i<=9;i++) if(work(step+1,i)){ v[i]=1; a[step+1]=i; dfs(step+1); v[i]=0; } } int main() { //freopen("1.in","r",stdin); //freopen("1.out","w",stdout); while (~scanf("%d",&p)){ for(int i=1;i<=9;i++){ v[i]=1; a[1]=i; dfs(1); v[i]=0; } if(ans==0)printf("NO\n"); else { printf("%d\n%d\n",ans,b[1]); printf("%d %d\n",b[2],b[3]); printf("%d %d\n",b[4],b[5]); printf("%d %d %d %d\n",b[6],b[7],b[8],b[9]); } } return 0; }
问题 F: 室友A的PY交易
题目描述
CC和TT在宿舍忙着写课设,他们决定由下述游戏的败者去拿外卖:
室友A想一个[1,N]中的数字X,两人轮流猜一个猜一个数字,恰好猜中X的人算负;否则室友A将告诉两人当前猜的数字是比X大还是比X小,这样一来猜测的范围就会变小(下一轮猜的数必须在X所在的那一半区间内)。初始范围是[1,N]。
室友A已经看透了一切,私下告诉了两人X是多少。现在,CC和TT都知道X是多少,且两个人都采取最优策略。若总是CC先猜,求X∈[1,N]可以使TT获胜的X的数量。
输入
第一行一个整数T表示数据组数。
接下来T行,每行一个正整数N。
1 <= T <= 100000
1 <= N <= 10000000
输出
T行每行一个整数表示答案。
样例输入
1
3
样例输出
1
题解
可以说是最简单的博弈题了,就是直接在浏览器写了交上去抢一血那种(:з)∠)
数轴抽象成一根棍子,中间X的位置有炸弹,两人轮流从任一端切去一段,先切到炸弹的人输。
设想X在正中间时,先手必败,因为先手切去一段破坏左右平衡后,后手可以在另一侧模拟一样的操作,将棍子恢复平衡。
那么同理,X不在正中间时,先手必胜,先手创造平衡条件即可。
棍子长度为奇数时,只有X在正中间时后手胜,输出1
长度为偶数时,输出0
这类博弈题目还是蛮有趣的,关键词包括“双方使用最优策略”
可以从NIM博弈(取石子游戏)开始学习,百度一搜一大把
这篇回答也不错https://www.zhihu.com/question/29910524
在正规比赛中,博弈一般是作为一种思想出现,与树、图等结构结合,而不是什么取石子、切棍子裸题。
#include <stdio.h>int main(){ freopen("test2.in", "r", stdin); freopen("test2.out", "w", stdout); int T, N; scanf("%d", &T); while(T--) { scanf("%d", &N); printf("%d\n", N % 2); } return 0;}
问题 G: 小明的游戏
题目描述
小明喜欢数字,现在小明想把一个数字拆分成若干个奇数的乘积,但他不知道
能不能拆分成功,你能帮帮他么
给你n个数,每个数都在int范围内
0 < n <= 1e5
单样例
输入
n
x1x2…xn
输出
n行,每行一个输出”YES”或”NO”(不包括引号)
样例输入
2
3 6
样例输出
YES
NO
题解
#include<bits/stdc++.h>using namespace std;int main(int argc, char const *argv[]){ int n,x; cin >> n; for(int i=1;i<=n;i++){ cin >> x; printf("%s\n",x%2 ? "YES" : "NO" ); } return 0;}
问题 H: 值日生
题目描述
八年级的Vova今天在课堂上值班。上课之后,他走进办公室洗板子,并在上面找到了n号。他问这个数字是什么,数学老师Inna Petrovna回答Vova说,n是一年级学生算术任务的答案。在教科书中,给出了某个正整数 x。n为十进制x加上各位上的数字的 和。
由于数字n很小,Vova很快就猜到了在教科书中可能出现哪个x。现在他想得到一个程序,它将搜索任意值为n的所有合适的x值,或者确定这个x不存在。为Vova写一个这样的程序
输入
第一行包含整数n(1≤ n ≤10^9)。
输出
在第一行打印一个整数k 表示满足要求的方案
后k行按照升序打印满足要求的数字
样例输入
21
20
样例输出
1
15
0
提示
15+1+5=21,只有一个满足要求
题解
最多也就是个9位数,因此最多就是在原来的数字基础上加9*9=81,大可以直接写100
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<string>#include<vector>#include<stack>#include<set>#include<map>#include<queue>#include<algorithm>#define ll long longusing namespace std;const int maxn=10000;bool judge(int num,int ans){ int tmp=num; while(num!=0){ int tm=num%10; num/=10; tmp+=tm; } if(tmp==ans) return true; else return false;}int main(){ // freopen("1.in","r",stdin); // freopen("1.out","w",stdout); int n; while(~scanf("%d",&n)){ std::vector<int> v; for(int i=max(1,n-100);i<=n;i++){ if(judge(i,n)) v.push_back(i); } printf("%d\n",v.size()); for(int i=0;i<v.size();i++){ printf("%d\n",v[i]); } } return 0;}
- --12月月赛题解--
- nyist14年3月月赛题解
- 洛谷5月月赛R1题解报告
- 备战12月月赛
- [bzoj-4832][Lydsy2017年4月月赛]抵制克苏恩 题解
- 洛谷10月月赛R2·浴谷八连测R3 -Chtholly- 1、2题题解
- CSU5月月赛
- FZU 10月月赛
- 浙大 4月月赛
- 洛谷8月月赛
- csu8月月赛,csuoj1978
- 洛谷 9月月赛
- buct12月月赛总结
- 月月月月月月月月
- Code+ 2017年12月月赛练习题 晨跑
- Code+12月月赛比赛过程记录(个人向)
- Vijos 10月月赛记录
- 【10月月赛T9】射命丸文
- 实现一个可下拉选择的TabLayout
- HTTP method names must be tokens
- 同步工具CyclicBarrier
- unity 移动端(仅安卓)读写Xml
- Java中Comparable和Comparator区别小结
- --12月月赛题解--
- Bloom Filter算法
- python3中的md5加密
- Android 状态栏操作,你想知道的都在这里了
- 后续文章在博客园更新
- 效率.效率.还是效率
- Android Study Material Design 十六 动画实践以及拓展
- markdown 语法高亮支持
- Objective-C Runtime 运行时(3)