给正序对数求原数组
假设 正序对数是
0
1
2
1
2
0\; 1 \;2\; 1\; 2
01212
解决:
- 先管正序对数小的,从小往大放
- 正序对数相同时,从右往左放
0
0
0
0
0
0 \; 0 \; 0\; 0 \; 0
00000
1
0
0
0
0
1\; 0\; 0\; 0 \; 0
10000
1
3
0
2
0
1\; 3\; 0 \; 2\; 0
13020
1
3
5
2
4
1\; 3 \; 5 \; 2 \; 4
13524
例题
这题需要根据残缺的数组,补齐原数组
#include<bits/stdc++.h>
#include<cstring>
#include<string>
using namespace std;
typedef long long ll;
#define SIZE (1000000+10)
int a[SIZE];
int b[SIZE];
int flag[SIZE];
vector<int>pot[SIZE];
int main() {
int i,j,n,k,p,x;
scanf("%d%d",&n,&k);
for(i=0;i<k;i++){
scanf("%d%d",&p,&x);
b[p]=x;
}
int maxn=0;
for(i=1;i<=n;i++){
if(b[i]==0)b[i]=b[i-1]+1;
else {
if(b[i]>maxn+1){
cout<<-1<<endl;
return 0;
}
}
maxn=max(maxn,b[i]);
pot[b[i]].push_back(i);
}
int ans=1;
for(i=1;i<=n;i++){
for(j=pot[i].size()-1;j>=0;j--){
a[pot[i][j]]=ans++;
}
}
//for(i=1;i<=n;i++)printf("%d ",b[i]);cout<<endl;
for(i=1;i<=n;i++)printf("%d ",a[i]);cout<<endl;
return 0;
}
给逆序对数求原数组(原数各不相同
排序
本题关键是得到原数组
- 放入 0 0 1 2 . . . x − 1 x x + 1 . . . n − 2 0\;0 \;1 \;2\; ...\;\;x-1\; x \;x+1\;... n-2 0012...x−1xx+1...n−2
- 多余的数从第二个位置开始加 ,可以得到逆序对数 0 1 2 . . . x x x + 1... n − 2 0\; 1 \;2 \;...x\; x\; x+1... \;n-2 012...xxx+1...n−2
- 然后再用当前位置扣去数字,可以得到正序对数 0 0 1 1 . . . 1 0 . . . 0 0\; 0\; 1 \;1\; ... \;1\; 0 \;... \;0 \; 0011...10...0
- 先放0 ,再放1,从右往左放
#include<bits/stdc++.h>
using namespace std;
const int Size = 1e5 + 10;
#define ll long long
#define debug(x) {cout<<#x<<" = "<<x<<" ";}
#define debug1(a) {debug(a);cout<<endl;}
#define debug2(a,b) {debug(a);debug1(b);}
#define debug3(a,b,c) {debug(a);debug2(b,c);}
#define debugvec(x,n) {cout<<#x<<": ";for(int asd=0;asd<n;asd++)cout<<x[asd]<<" ";cout<<endl;}
#define debugvector(x) {cout<<#x<<": ";for(int asd=0;asd<x.size();asd++)cout<<x[asd]<<" ";cout<<endl;}
#define debugvectorstring(x) {cout<<#x<<": ";for (auto& s : x) printf("%s", s.c_str());;cout<<endl;}
int n, k = 100;
string s, ans;
vector<int>v;
void ini() {
int i, t;
n = 1;
while (n * (n - 1) / 2 < k) n++;
v.push_back(0);
for (i = 0; i < n - 1; i++)v.push_back(i);
t = k - (n - 2) * (n - 1) / 2;
//debug3(k, (n - 2) * (n - 1) / 2, t);
for (i = n - 1; t; t--, i--)v[i]++;
for (i = 0; i < n; i++)v[i] = i - v[i];
//debugvec(v, n);
}
void sovle() {
int i;
char ch = 'a';
s.resize(n);
for (i = n - 1; i >= 0; i--)if (!v[i]) s[i] = ch++;
for (i = n - 1; i >= 0; i--)if (v[i]) s[i] = ch++;
cout << s << endl;
}
int main() {
//freopen("C:\\Users\\31531\\Desktop\\input.txt", "r", stdin);
ini();
sovle();
return 0;
}
给逆序对数求原数组(原数可相同
当 k ≤ 26 ( 26 − 1 ) 2 = 325 时 k \leq \cfrac{26(26-1)}{2}=325时 k≤226(26−1)=325时
- 放入 0 0 1 2 . . . x − 1 x x + 1 . . . n − 2 0\;0 \;1 \;2\; ...\;\;x-1\; x \;x+1\;... n-2 0012...x−1xx+1...n−2
- 从倒二位开始 v [ i ] + + v[i]++ v[i]++,每次往前挪两格 i − = 2 i-=2 i−=2
- 从正二位或者正三位开始 v [ i ] + + v[i]++ v[i]++,每次往后挪两格 i + = 2 i+=2 i+=2
- 已经是递增的顺序了,直接从右往左放
#include<bits/stdc++.h>
using namespace std;
const int Size = 3e3 + 10;
#define ll long long
#define debug(x) {cout<<#x<<" = "<<x<<" ";}
#define debug1(a) {debug(a);cout<<endl;}
#define debug2(a,b) {debug(a);debug1(b);}
#define debug3(a,b,c) {debug(a);debug2(b,c);}
#define debugvec(x,n) {cout<<#x<<": ";for(int asd=0;asd<n;asd++)cout<<x[asd]<<" ";cout<<endl;}
#define debugvector(x) {cout<<#x<<": ";for(int asd=0;asd<x.size();asd++)cout<<x[asd]<<" ";cout<<endl;}
#define debugvectorstring(x) {cout<<#x<<": ";for (auto& s : x) printf("%s", s.c_str());;cout<<endl;}
string s = "";
int n,k=100;
vector<int>v;
void debugs(string s) {
for (auto ch : s) {
printf("%3c", ch);
}
cout << endl;
int p[2] = { 0,0 };
for (int i = 0; i < s.size(); i++) {
int cnt = 0;
for (int j = i - 1; j >= 0; j--) {
if (s[j] > s[i]) {
cnt++;
}
}
p[1] += cnt;
printf("%3d", cnt);
}
cout << endl;
//debug2(p[0], p[1]);
}
void ini() {
int i, t;
n = 1;
while (n * (n - 1) / 2 < k) n++;
t = k - (n - 1) * (n - 2) / 2;
v.push_back(0);
for (i = 0; i < n - 1; i++)v.push_back(i);
//debugvec(v, n);
for (i = n - 2; i > 0 && t; i-=2, t--)v[i]++;
//debugvec(v, n);
for (i = 1 + (n % 2); t; t--, i += 2)v[i]++;
//debugvec(v, n);
}
void solve() {
s.resize(n);
char ch = 'a';
s[n - 1] = ch;
for (int i = n - 2; i >= 0; i--) {
if (v[i] == v[i + 1])s[i] = ch;
else s[i] = ++ch;
}
}
int flag = 26 * 25 / 2;
int main() {
//freopen("C:\\Users\\31531\\Desktop\\input.txt", "r", stdin);
//debugs("bbaa");
//debugs("jihgfeeddccbbaa");
cin >> k;
if (k > flag)while (1);
ini();
solve();
cout << s;
return 0;
}
当 k > 26 ( 26 − 1 ) 2 时 k>\cfrac{26(26-1)}{2}时 k>226(26−1)时待续
- 2237
- gzyyxxwwvvuuttssrrqqppoonnmmllkkkjjjiiihhhgggffffeeeeddddccccbbbbaaaa