【牛客练习赛11】A B D E
2018-01-27 17:05
381 查看
A 假的线段树
链接:https://www.nowcoder.com/acm/contest/59/A
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
给你一个长为n的序列a,有m次操作
1.把区间[l,r]内所有x变成y
2.查询区间[l,r]内第k小值
输入描述:
第一行两个数n,m
第二行n个数表示序列a
后面m行
1 l r x y :把区间[l,r]中所有x变成y
2 l r k :查询区间[l,r]中的第k小值
输出描述:
对于每个询问,输出一个数表示答案
示例1
输入
3 3
2 3 3
2 1 3 1
1 1 3 3 1
2 1 3 2
输出
2
1
备注:
对于100%的数据,1 <= n, m , ai <= 1000
题解: 看数据范围,操作一 暴力没有问题。操作二 ,我们可以用一个容器有序存储所截序列,然后找到第k项就行了。这里要用mutiset ,因为有重复数据。
代码
B 假的字符串
题解链接
D 求距离
链接:https://www.nowcoder.com/acm/contest/59/D
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
给你一个1 -> n的排列,现在有一次机会可以交换两个数的位置,求交换后最小值和最大值之间的最大距离是多少?
输入描述:
第一行一个数n
之后一行n个数表示这个排列
输出描述:
输出一行一个数表示答案
示例1
输入
5
4 5 1 3 2
输出
3
说明
把1和2交换后
序列为4 5 2 3 1
最大值5在数组的2位置,最小值1在数组的5位置
距离为3
备注:
对于100%的数据,1 <= n <= 100
水题
代码
E 求最值
链接:https://www.nowcoder.com/acm/contest/59/E
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
给你一个长为n的序列a
定义f(i,j)=(i-j)2+g(i,j)2
g是这样的一个函数
求最小的f(i,j)的值,i!=j
输入描述:
第一行一个数n
之后一行n个数表示序列a
输出描述:
输出一行一个数表示答案
示例1
输入
4
1 0 0 -1
输出
1
备注:
对于100%的数据,2 <= n <= 100000 , |ai| <= 10000
分析:cf原题,把题目公式变形一下 ,就好看了
f(i,j) = (j-i)^2 + (sum[j] - sum[i] ) ^2
距离公式,所以就是求最近点对问题
代码
还有就是 可以暴力 我们可以暴力个几千个点 也是可以过的。
链接:https://www.nowcoder.com/acm/contest/59/A
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
给你一个长为n的序列a,有m次操作
1.把区间[l,r]内所有x变成y
2.查询区间[l,r]内第k小值
输入描述:
第一行两个数n,m
第二行n个数表示序列a
后面m行
1 l r x y :把区间[l,r]中所有x变成y
2 l r k :查询区间[l,r]中的第k小值
输出描述:
对于每个询问,输出一个数表示答案
示例1
输入
3 3
2 3 3
2 1 3 1
1 1 3 3 1
2 1 3 2
输出
2
1
备注:
对于100%的数据,1 <= n, m , ai <= 1000
题解: 看数据范围,操作一 暴力没有问题。操作二 ,我们可以用一个容器有序存储所截序列,然后找到第k项就行了。这里要用mutiset ,因为有重复数据。
代码
#include<bits/stdc++.h> using namespace std; const int MAXN = 1e3+11; int a[MAXN]; multiset<int>S; multiset<int>::iterator it; int main() { int n,m;scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); while(m--){ int l,r,op,x,y; scanf("%d%d%d%d",&op,&l,&r,&x); if(op==1){ scanf("%d",&y); for(int i=l;i<=r;i++){ if(a[i]==x) a[i]=y; } }else { S.clear(); for(int i=l;i<=r;i++){ S.insert(a[i]); } int i=1; for(it=S.begin();it!=S.end();it++,i++){ if(i==x) { cout<<*(it)<<endl; break; } } } } return 0; }
B 假的字符串
题解链接
D 求距离
链接:https://www.nowcoder.com/acm/contest/59/D
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
给你一个1 -> n的排列,现在有一次机会可以交换两个数的位置,求交换后最小值和最大值之间的最大距离是多少?
输入描述:
第一行一个数n
之后一行n个数表示这个排列
输出描述:
输出一行一个数表示答案
示例1
输入
5
4 5 1 3 2
输出
3
说明
把1和2交换后
序列为4 5 2 3 1
最大值5在数组的2位置,最小值1在数组的5位置
距离为3
备注:
对于100%的数据,1 <= n <= 100
水题
代码
#include<bits/stdc++.h> using namespace std; const int inf = 0x3f3f3f3f; const int MAXN = 1e3+11; int arr[MAXN]; struct node{ int pos,num; }mx,mn; int main(){ int n; while(scanf("%d",&n)!=EOF){ mx.num=-1; mn.num=inf; for(int i=0;i<n;i++){ scanf("%d",&arr[i]); if(arr[i]<mn.num){ mn.num=arr[i]; mn.pos=i; } if(arr[i]>mx.num){ mx.num=arr[i];mx.pos=i; } } int x = max(abs(n-1-mn.pos),abs(mn.pos)); int y = max(abs(n-1-mx.pos),abs(mx.pos)); printf("%d\n",max(x,y)); } return 0; }
E 求最值
链接:https://www.nowcoder.com/acm/contest/59/E
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
给你一个长为n的序列a
定义f(i,j)=(i-j)2+g(i,j)2
g是这样的一个函数
求最小的f(i,j)的值,i!=j
输入描述:
第一行一个数n
之后一行n个数表示序列a
输出描述:
输出一行一个数表示答案
示例1
输入
4
1 0 0 -1
输出
1
备注:
对于100%的数据,2 <= n <= 100000 , |ai| <= 10000
分析:cf原题,把题目公式变形一下 ,就好看了
f(i,j) = (j-i)^2 + (sum[j] - sum[i] ) ^2
距离公式,所以就是求最近点对问题
代码
#include<bits/stdc++.h> using namespace std; #define LL long long const int MAXN = 100000 + 10; const int MAXM = 1e6; const int mod = 1e9+7; const LL inf = 0x3f3f3f3f3f3f3f; struct Node{ LL x,y; }Point[MAXN],Q[MAXN]; bool cmpx(Node a,Node b) { return a.x<b.x ; } bool cmpy(Node a,Node b){ return a.y<b.y ; } LL sqr(LL a) { return a*a; } LL GetDis(Node a,Node b){ return sqr(a.x-b.x)+sqr(a.y-b.y); } LL DIV(int le,int ri){ LL ret=inf; if(le==ri) return ret; if(le+1==ri) return GetDis(Point[le],Point[ri]); int mid=(le+ri)>>1; LL d1=DIV(le,mid); LL d2=DIV(mid+1,ri); ret=min(d1,d2); double d=sqrt((double)ret); int k=0; for(int i=mid;i>=le;i--) { if(Point[mid].x-Point[i].x>(LL)d) break; Q[++k]=Point[i]; } for(int i=mid+1;i<=ri;i++) { if(Point[i].x-Point[mid].x>(LL)d) break; Q[++k]=Point[i]; } sort(Q+1,Q+1+k,cmpy); for(int i=1;i<k;i++){ for(int j=i+1;j<=k&&Q[j].y-Q[i].y<=(LL)d;j++) ret=min(ret,GetDis(Q[j],Q[i])); } return ret; } int a[MAXN]; int main(){ int n;scanf("%d",&n); LL sum=0; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); sum+=a[i]; Point[i].x=i; Point[i].y=sum; } sort(Point+1,Point+1+n,cmpx); printf("%lld\n",DIV(1,n)); return 0; }
还有就是 可以暴力 我们可以暴力个几千个点 也是可以过的。
相关文章推荐
- 牛客练习赛11 E求最值 (平面最近点对问题)
- 牛客练习赛11-B-假的字符串(字典树+拓扑)
- 牛客练习赛11 E、求最值
- 牛客练习赛 11
- 牛客练习赛11 B、假的字符串
- 牛客网NowCoder 牛客练习赛11-A.假的线段树 D. 求距离
- 牛客练习赛11 B-假的字符串(字典树+拓扑排序找环)
- 牛客练习赛3 E - 绝对半径2051
- 牛客练习赛12 B题
- 牛客练习赛13 B 幸运数字Ⅱ【前缀和 + 位运算 + 二分】
- 牛客练习赛13 --d(逆康拓展开)
- 牛客练习赛13-D-幸运数字Ⅳ(康托展开 & 逆康托展开)
- 牛客练习赛17
- 牛客练习赛6 B题 点权和
- 牛客练习赛6 D 世界上最可爱的珂朵莉 贪心
- 牛客练习赛6 B 点权和 树点权和
- 牛客练习赛3 F 监视任务 每个区间K个 树状数组+贪心
- 牛客练习赛7 购物 DP 初始化问题
- 牛客练习赛7 E 珂朵莉的数列 (只有思路)
- 牛客练习赛8解题报告