题目
具体来说, 你现在知道了q个区间, 第i个区间是[lᵢ,rᵢ],,同时杰宝还会给你一个常数 B。随后, 你需要将区间按
∣
l
B
∣
| \frac {l}{B}|
∣Bl∣为第一关键字从小到大, 按r为第二关键字从小到大排序, 按编号为第三关键字从小到大排序。
特别地, 当两个区间先按第一关键字的大小关系进行排序。当第一关键字相同, 按第二关键字的大小关系排序。当第二关键字也相同, 按第三关键字大小关系排序。
你需要按区间排序后的顺序, 输出区间原先的编号。
输入描述
第一行, 包含两个整数,
q
,
B
(
1
≤
,
B
≤
1
0
5
)
。
q,B(1≤,B≤10⁵)。
q,B(1≤,B≤105)。
接下来q行, 第i 行包含两个整数,
l
i
,
r
i
(
1
≤
l
≤
r
≤
1
0
5
)
。
lᵢ,rᵢ(1≤l≤r≤10⁵)。
li,ri(1≤l≤r≤105)。
输出描述
输出一行, 包含q个整数, 表示答案。
输入样例:
8 3
1 7
2 5
3 8
5 6
4 6
6 8
7 8
6 6
输出范例:
2 1 4 5 3 8 6 7
结构体思维
当时在赛场上也想这么整,但是不知道为什么老是输出空的,大概需要注意的就是,
- 结构体数组在申请空间时候必然会调用默认构造函数或者你设置的无参构造函数
- 还有就是要注意设置无参构造函数的时候如果打算什么都不做,还是要声明一个空的函数体。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define For for(int i=1;i<=n;i++)
#define rFor for(int i=n;i>0;i--)
#define rep(i,sta,end) for(int i=sta;i<=end;i++)
#define Whole(x) for(auto item:x)
const int N = 1e5;
int B;
struct tar{
int index;
pair<int,int> qu;
tar(){};
tar(int in,pair<int,int> q){
index=in;
qu=q;
}
};
bool cmp(tar a,tar b){
if(a.qu.first/B!=b.qu.first/B)
return a.qu.first/B<b.qu.first/B;
if(a.qu.second!=b.qu.second)
return a.qu.second<b.qu.second;
return a.index<b.index;
}
inline void solve() {
int n;
cin>>n>>B;
vector<tar> arr;
For {
pair<int,int> temp;
cin>>temp.first>>temp.second;
tar tmp(i,temp);
arr.emplace_back(tmp);
};
sort(arr.begin(),arr.end(),cmp);
Whole(arr){
cout<<item.index<<" ";
}
cout<<endl;
}
又或者可以重载一个结构体内部的‘<’符号
struct tar {
int index;
pair<int,int> qu;
tar(){};
tar(int in,pair<int,int> q):index(in), qu(q){};
bool operator < (const tar& t){
if(qu.first/B!=t.qu.first/B)
return qu.first/B<t.qu.first/B;
if(qu.second!=t.qu.second)
return qu.second<t.qu.second;
return index<t.index;
}
};
数组思维
注意,下面是我一开始的代码,注意前四行代码
#define For for(int i=1;i<=n;i++)
int B;
int n;
vector<int> xu(n+10),l(n+10),r(n+10);
bool cmp(int a,int b){
if(l[a]/B!=l[b]/B)
return l[a]/B<l[b]/B;
else if(r[a]!=r[b])
return r[a]<r[b];
else return a<b;
}
inline void solve() {
cin>>n>>B;
For {
xu[i]=i;
cin>>l[i]>>r[i];
}
sort(xu.begin()+1,xu.begin()+1+n,cmp);
For cout<<xu[i]<<" ";
cout<<endl;
}
比如这个代码,我的思路是对的,但是有些很简单的样例比如
输入:
10 5
4 2
8 9
10 5
8 5
10 1
10 1
5 7
5 2
7 5
7 2
输出:
1 8 10 4 9 7 2 5 6 3
他会耗时很长时间,然后去不断猜测问题
Long Long time passed
终于找到了问题
后面是改正过的
#define For for(int i=1;i<=n;i++)
int B;
int n;
vector<int> xu,l,r;
bool cmp(int a,int b){
if(l[a]/B!=l[b]/B)
return l[a]/B<l[b]/B;
else if(r[a]!=r[b])
return r[a]<r[b];
else return a<b;
}
inline void solve() {
cin>>n>>B;
xu.resize(n+10),l.resize(n+10),r.resize(n+10);
For {
xu[i]=i;
cin>>l[i]>>r[i];
}
sort(xu.begin()+1,xu.begin()+1+n,cmp);
For cout<<xu[i]<<" ";
cout<<endl;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int num = 1;
//cin>>num;
while(num--)
solve();
}
前四行被改变了,xu,l,r,这三个数组的size在后面输入了n以后再确定,因为一开始n没有被初始化,默认为零,xu,l,r,这三个数组的size默认为0+10,因此后来在输入的时候会超范围会RE。