题目链接
题意:
给 一 个 长 度 为 n 的 数 列 , 找 出 第 k 小 数 给一个长度为n的数列,找出第k小数 给一个长度为n的数列,找出第k小数
题解:
本 来 是 一 个 签 到 题 , 结 果 数 据 范 围 给 出 了 本来是一个签到题,结果数据范围给出了 本来是一个签到题,结果数据范围给出了
大 批 的 w a 就 出 现 了 大批的wa就出现了 大批的wa就出现了
最 后 n < = 5 e 6 , 直 接 快 读 加 s o r t 找 a k 就 行 最后n<=5e6,直接快读加sort找a_k就行 最后n<=5e6,直接快读加sort找ak就行
AC代码
/*
Author:zzugzx
Lang:C++
Blog:blog.csdn.net/qq_43756519
*/
#include
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=4e6+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int a[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int _;
while(cin>>_){
while(_--){
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)cin>>a[i];
sort(a+1,a+1+n);
cout<<a[k]<<endl;
}
}
return 0;
}
题意:
有 n 个 不 重 复 点 , 任 意 两 个 点 可 以 组 成 线 段 有n个不重复点,任意两个点可以组成线段 有n个不重复点,任意两个点可以组成线段
能 找 出 最 多 多 少 条 线 段 不 互 相 平 行 或 重 合 能找出最多多少条线段不互相平行或重合 能找出最多多少条线段不互相平行或重合
题解:
由 于 几 条 线 平 行 只 能 选 一 条 由于几条线平行只能选一条 由于几条线平行只能选一条
所 以 直 接 看 每 条 线 的 斜 率 所以直接看每条线的斜率 所以直接看每条线的斜率
如 果 重 复 出 现 , 那 么 后 面 的 就 不 能 被 继 续 选 中 如果重复出现,那么后面的就不能被继续选中 如果重复出现,那么后面的就不能被继续选中
最 直 接 的 方 法 , s e t 存 斜 率 , 判 一 下 斜 率 不 存 在 的 情 况 是 否 出 现 最直接的方法,set存斜率,判一下斜率不存在的情况是否出现 最直接的方法,set存斜率,判一下斜率不存在的情况是否出现
如 果 出 现 , 不 管 几 次 都 加 1 , 然 后 看 s e t . s i z e ( ) 如果出现,不管几次都加1,然后看set.size() 如果出现,不管几次都加1,然后看set.size()
但 是 斜 率 会 出 现 小 数 , 需 要 用 d o u b l e , s e t 可 能 会 被 卡 精 度 ( 这 道 题 没 有 ) 但是斜率会出现小数,需要用double,set可能会被卡精度(这道题没有) 但是斜率会出现小数,需要用double,set可能会被卡精度(这道题没有)
所 以 可 以 取 出 所 有 斜 率 , 排 序 一 下 , 自 己 手 动 判 重 所以可以取出所有斜率,排序一下,自己手动判重 所以可以取出所有斜率,排序一下,自己手动判重
手 动 用 x − y < e p s 判 相 等 不 会 出 现 被 卡 精 度 的 情 况 手动用x-y
AC代码
/*
Author:zzugzx
Lang:C++
Blog:blog.csdn.net/qq_43756519
*/
#include
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=1e6+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
double x[210],y[210];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>x[i]>>y[i];
set<double> s;
int f=0;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++){
if(!(y[i]-y[j])){f=1;continue;}
s.insert((x[i]-x[j])/(y[i]-y[j]));
}
cout<<s.size()+f;
return 0;
}
题意:
n 个 小 朋 友 围 成 一 个 圈 , 给 出 相 邻 两 个 小 朋 友 的 距 离 n个小朋友围成一个圈,给出相邻两个小朋友的距离 n个小朋友围成一个圈,给出相邻两个小朋友的距离
最 后 问 任 意 两 个 小 朋 友 的 最 远 距 离 最后问任意两个小朋友的最远距离 最后问任意两个小朋友的最远距离
题解:
直 接 操 作 可 以 是 枚 举 任 意 两 个 小 朋 友 , 看 他 俩 的 距 离 直接操作可以是枚举任意两个小朋友,看他俩的距离 直接操作可以是枚举任意两个小朋友,看他俩的距离
但 是 这 样 会 超 时 但是这样会超时 但是这样会超时
从 一 个 朋 友 的 左 边 出 发 到 右 边 , 每 个 小 朋 友 和 他 的 距 离 一 定 是 个 凸 函 数 从一个朋友的左边出发到右边,每个小朋友和他的距离一定是个凸函数 从一个朋友的左边出发到右边,每个小朋友和他的距离一定是个凸函数
所 以 可 以 考 虑 三 分 , 对 每 个 小 朋 友 进 行 三 分 找 最 远 距 离 所以可以考虑三分,对每个小朋友进行三分找最远距离 所以可以考虑三分,对每个小朋友进行三分找最远距离
通 过 前 缀 和 维 护 任 意 两 个 小 朋 友 直 接 的 距 离 通过前缀和维护任意两个小朋友直接的距离 通过前缀和维护任意两个小朋友直接的距离
环 的 距 离 有 两 个 方 向 , 所 以 要 记 得 两 个 方 向 取 距 离 环的距离有两个方向,所以要记得两个方向取距离 环的距离有两个方向,所以要记得两个方向取距离
AC代码
/*
Author:zzugzx
Lang:C++
Blog:blog.csdn.net/qq_43756519
*/
#include
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=1e6+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
ll i,a[maxn];
ll s[maxn],sum;
ll check(ll x){
ll y=s[x]-s[i-1];
return min(y,sum-y);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n;cin>>n;
for(i=1;i<=n;i++)
cin>>a[i],sum+=a[i];
for(i=1;i<=2*n;i++){
if(i<=n)s[i]=s[i-1]+a[i];
else s[i]=s[i-1]+a[i-n];
}
ll ans=0;
for(i=1;i<=n;i++){
ll l=i,r=i+n;
while(l+10<r){
ll lm=l+(r-l)/3,rm=r-(r-l)/3;
if(check(lm)>=check(rm))r=rm;
else l=lm;
}
for(ll j=l;j<=r;j++)
ans=max(ans,check(j));
}
cout<<ans;
return 0;
}
题意:
猜 数 游 戏 , 你 猜 一 个 数 , 裁 判 告 诉 你 答 案 比 这 个 数 大 还 是 小 或 等 于 猜数游戏,你猜一个数,裁判告诉你答案比这个数大还是小或等于 猜数游戏,你猜一个数,裁判告诉你答案比这个数大还是小或等于
但 是 裁 判 会 忘 记 了 自 己 说 的 但是裁判会忘记了自己说的 但是裁判会忘记了自己说的
所 以 裁 判 说 的 不 一 定 正 确 , 告 诉 你 n 条 裁 判 说 的 所以裁判说的不一定正确,告诉你n条裁判说的 所以裁判说的不一定正确,告诉你n条裁判说的
判 断 裁 判 说 的 是 正 确 的 可 能 有 几 句 判断裁判说的是正确的可能有几句 判断裁判说的是正确的可能有几句
题解:
这 个 总 容 易 想 到 的 就 是 枚 举 这 个 数 这个总容易想到的就是枚举这个数 这个总容易想到的就是枚举这个数
但 是 这 个 数 太 大 , 是 在 i n t 范 围 内 的 所 有 数 但是这个数太大,是在int范围内的所有数 但是这个数太大,是在int范围内的所有数
所 以 可 能 会 想 到 三 分 , 但 是 通 过 自 己 写 几 个 数 据 实 验 一 下 所以可能会想到三分,但是通过自己写几个数据实验一下 所以可能会想到三分,但是通过自己写几个数据实验一下
发 现 并 不 是 一 个 凸 函 数 发现并不是一个凸函数 发现并不是一个凸函数
所 以 我 们 就 考 虑 用 差 分 来 做 , 去 计 数 每 一 条 正 确 的 区 间 所以我们就考虑用差分来做,去计数每一条正确的区间 所以我们就考虑用差分来做,去计数每一条正确的区间
由 于 数 较 大 , 所 以 要 进 行 离 散 , 将 给 出 的 数 和 左 右 相 邻 的 数 一 起 离 散 由于数较大,所以要进行离散,将给出的数和左右相邻的数一起离散 由于数较大,所以要进行离散,将给出的数和左右相邻的数一起离散
如 果 答 案 大 于 某 个 数 , 把 这 个 数 对 于 的 离 散 后 的 位 置 右 边 用 差 分 加 一 如果答案大于某个数,把这个数对于的离散后的位置右边用差分加一 如果答案大于某个数,把这个数对于的离散后的位置右边用差分加一
相 等 就 是 这 个 点 加 一 , 小 于 的 话 同 理 大 于 的 情 况 相等就是这个点加一,小于的话同理大于的情况 相等就是这个点加一,小于的话同理大于的情况
最 后 统 计 每 个 数 的 正 确 情 况 , 找 到 最 大 的 最后统计每个数的正确情况,找到最大的 最后统计每个数的正确情况,找到最大的
AC代码
/*
Author:zzugzx
Lang:C++
Blog:blog.csdn.net/qq_43756519
*/
#include
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=1e6+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int n;
ll x[maxn],a[maxn],c[maxn];
char y[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
cin>>n;
int len=0;
for(int i=1;i<=n;i++){
cin>>x[i]>>y[i];
c[++len]=x[i];
c[++len]=x[i]-1;
c[++len]=x[i]+1;
}
sort(c+1,c+1+len);
len=unique(c+1,c+1+len)-c-1;
for(int i=1;i<=n;i++){
int p=lower_bound(c+1,c+1+len,x[i])-c;
if(y[i]=='.')a[p]++,a[p+1]--;
if(y[i]=='-')a[p+1]++,a[len+10]--;
if(y[i]=='+')a[1]++,a[p]--;
}
ll ans=0;
for(int i=1;i<=len+10;i++)
a[i]+=a[i-1],ans=max(ans,a[i]);
cout<<ans;
return 0;
}
题意:
有 n 个 无 序 的 数 , 通 过 最 少 多 少 次 交 换 可 以 使 他 有 序 有n个无序的数,通过最少多少次交换可以使他有序 有n个无序的数,通过最少多少次交换可以使他有序
题解:
交 换 数 , 最 差 情 况 是 n 次 , 把 每 个 数 交 换 到 对 应 的 位 置 交换数,最差情况是n次,把每个数交换到对应的位置 交换数,最差情况是n次,把每个数交换到对应的位置
但 是 如 果 出 现 如 下 情 况 但是如果出现如下情况 但是如果出现如下情况
比 如 数 列 1 , 4 , 2 , 3 , 5 , 6 比如数列1,4,2,3,5,6 比如数列1,4,2,3,5,6
这 里 的 4 , 3 , 2 。 2 的 位 置 放 着 4 , 4 的 位 置 放 着 3 , 3 的 位 置 放 着 2 这里的4,3,2。2的位置放着4,4的位置放着3,3的位置放着2 这里的4,3,2。2的位置放着4,4的位置放着3,3的位置放着2
这 样 称 为 一 个 循 环 节 , 只 要 2 和 4 换 , 3 和 4 换 就 可 以 了 这样称为一个循环节,只要2和4换,3和4换就可以了 这样称为一个循环节,只要2和4换,3和4换就可以了
循 环 节 有 x 个 数 , 只 要 换 x − 1 个 数 就 可 以 让 所 有 数 都 归 位 循环节有x个数,只要换x-1个数就可以让所有数都归位 循环节有x个数,只要换x−1个数就可以让所有数都归位
所 以 就 是 , 有 几 个 循 环 节 就 可 以 少 换 几 次 所以就是,有几个循环节就可以少换几次 所以就是,有几个循环节就可以少换几次
总 共 是 n 次 , 那 么 最 后 结 果 就 是 用 n − 循 环 节 数 总共是n次,那么最后结果就是用n-循环节数 总共是n次,那么最后结果就是用n−循环节数
然 后 需 要 找 循 环 节 然后需要找循环节 然后需要找循环节
由 于 数 是 不 连 续 的 , 先 对 数 排 序 , 找 出 每 个 数 应 该 在 的 位 置 由于数是不连续的,先对数排序,找出每个数应该在的位置 由于数是不连续的,先对数排序,找出每个数应该在的位置
然 后 对 未 访 问 的 数 , 找 对 应 这 个 位 置 应 该 放 的 数 在 哪 然后对未访问的数,找对应这个位置应该放的数在哪 然后对未访问的数,找对应这个位置应该放的数在哪
直 到 再 次 找 到 这 个 循 环 节 的 头 为 止 直到再次找到这个循环节的头为止 直到再次找到这个循环节的头为止
AC代码
/*
Author:zzugzx
Lang:C++
Blog:blog.csdn.net/qq_43756519
*/
#include
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=1e6+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
bool flag[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n;cin>>n;
vector<int> v;
for(int i=1,x;i<=n;i++){
cin>>x;
v.pb(x);
}
map<int,int> m;
vector<int> v1=v;
sort(all(v1));
for(int i=0;i<n;i++)m[v1[i]]=i;
int ans=0;
for(int i=0;i<n;i++){
if(!flag[i]){
int j=i;
while(!flag[j]){
flag[j]=1;
j=m[v[j]];
}
ans++;
}
}
cout<<n-ans;
return 0;
}