Harbour.Space Scholarship Contest 2023-2024 (Div. 1 + Div. 2)
思路:
我们可以通过an和b的单调递减来从后往前遍历找ai,不妨b1=1,然后反向加一,最后特判一下a数组是否满足a1=x即可
#include
using namespace std;
#define int long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,a,n) for(int i=n;i>=a;i--)
#define pb push_back
#define SZ(v) ((int)v.size())
#define fs first
#define sc second
const int N=3e6+10,M=2e5;
typedef double db;
typedef pairpii;
int n,m,k,Q,cnt,t,a1,a2;
vectordel;
int a[N],b[200010];
int prime[N];
bool st[N];
mapmp;
void solve(){
int x,y,n;
std::cin>>x>>y>>n;
a[1]=x,a[n]=y;
int l=1;
per(i,2,n-1){
a[i]=a[i+1]-l;
l++;
//cout<>t;
while(t--)solve();
}
//-2 -2 -2 -2 0 0 0 0 0 3
思路:
我们可以发现如果k是偶数,我们交换一段区间可以将奇数位变为偶数位,偶数位变为奇数位,如果k位奇数,交换区间不会让奇数位变为偶数位,所有在执行方案一时k是偶数就直接排序即可,如果k位奇数偶数位排序,奇数位排序即可
#include
using namespace std;
#define int long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,a,n) for(int i=n;i>=a;i--)
#define pb push_back
#define SZ(v) ((int)v.size())
#define fs first
#define sc second
const int N=3e6+10,M=2e5;
typedef double db;
typedef pairpii;
int n,m,k,Q,cnt,t,a1,a2;
vectordel;
char a[N],b[N];
int prime[N];
bool st[N];
mapmp;
void solve(){
int n,k;std::cin>>n>>k;
string s;std::cin>>s;
if(k&1){
s = ' ' + s;
int cnt1 = 0;
int cnt2 = 0;
for (int i = 1; i < s.size(); i++) {
if (i % 2 != 0)a[cnt1++] = s[i];
else b[cnt2++] = s[i];
}
sort(a, a + cnt1);
sort(b, b + cnt2);
for (int i = 1,k=0,j=0; i <= n; i++) {
if (i % 2 == 1)std::cout << a[k++];
else std::cout << b[j++];
}
std::cout << endl;
}else{
sort(s.begin(),s.end());
std::cout<>t;
while(t--)solve();
}
//-2 -2 -2 -2 0 0 0 0 0 3
思路:
这个要想一想了,怎么可以让一个数尽量出现不超过两次呢,其实就是将n进行对n里面2的最高次幂的约数进行减去,怎么能说明这是对的呢,因为当你减去他这个2的最高次幂,后面不会在出现这个2的最高次幂,因为你减去这个最高次幂不会影响整体的最高次幂
我们可以分三种情况改变n值:
① 如果n是奇数,我们将n-1变为偶数
② 如果n是2的幂,将n-n/2
③ 如果n不算2的幂,找到2的最高次幂的约数,减去这个约数
#include
using namespace std;
#define int long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,a,n) for(int i=n;i>=a;i--)
#define pb push_back
#define SZ(v) ((int)v.size())
#define fs first
#define sc second
const int N=3e6+10,M=2e5;
typedef double db;
typedef pairpii;
int n,m,k,Q,cnt,t,a1,a2;
vectordel;
int a[N],b[N];
int prime[N];
bool st[N];
mapmp;
int lowbit(int x) {
return (-x)&x;
}
void solve(){
std::cin>>n;
int l=0,m=n;
while(n>1){
if(n&1){
a[l++]=n-1;
n--;
continue;
}
int x=n,orz=1;
while(x%orz==0){
orz*=2;
//if(x==orz)break;
}
orz/=2;
if(orz==x){
//cout<<"----1 "<>t;
while(t--)solve();
}
//-2 -2 -2 -2 0 0 0 0 0 3
思路:
首先想到,最优解法一定是从第一行操作到第n行,因为 i+1 行不会影响 i 行,反之会影响
只要知道当前位的倒转次数,就知道要不要倒转
假如 i 行区间[x,y]会倒转,i+1行区间[x-1,y+1]会倒转
操作的本质是让当前行 i 的区间 [j,j] 倒转
那就维护 倒转的两个边界,倒转次数就是个差分数组还原 ,换行同步更新边界就行
#include
using namespace std;
#define int long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,a,n) for(int i=n;i>=a;i--)
#define pb push_back
#define SZ(v) ((int)v.size())
#define fs first
#define sc second
const int N=3e6+10,M=2e5;
typedef double db;
typedef pairpii;
int n,m,k,Q,cnt,t,a1,a2;
vectordel;
int a[N],b[N];
int prime[N];
bool st[N];
mapmp;
int lowbit(int x) {
return (-x)&x;
}
void solve(){
int n;std::cin>>n;
vectors(n);
for(int i=0;i>s[i];
//差分加的部分,差分减的部分
vectorf(n+1),g(n+1);
vectora(n+1);
int op=0;
for(int i=0;i0;j--) g[j]=g[j-1];
}
std::cout<>t;
while(t--)solve();
}
//-2 -2 -2 -2 0 0 0 0 0 3
后面待跟新@_@