LINK
好家伙,一顿敲完才发现并不是按照二进制递增的这个规律,因为二进制递增无法保证一直有两个进制位为1,因此想到分开观察两个b的规律,
发现第一个b,在倒数第2个位置出现1次,在倒数第3个位置出现2次,在倒数第4个位置出现3次,……
而第二个b,配合着第一个b,第一个b位置固定时,第二个b从倒数第一个位置逐渐前移
注意
i
∗
(
i
+
1
)
/
2
i*(i+1)/2
i∗(i+1)/2 爆
i
n
t
int
int !!!
#include <iostream>
#include <algorithm>
using namespace std;
const int N=105;
#define int long long
signed main(){
int T,n,k;
cin>>T;
while(T--){
cin>>n>>k;
int i,p,q;
for(i=1;i<=n;i++){
if(i*(i+1)/2>=k)break;
}
p=n-i;//第一个b的位置
// q=i*(i+1)/2-k+p+1;
i--;
q=n-(k-i*(i+1)/2)+1;//第二个b,是从第n个位置往前推
// 要么遍历i时就一边为k连续减去i,q=n-k+1,否则 i*(i+1)/2就爆int
for(int j=1;j<=n;j++){
if(j==p||j==q)cout<<"b";
else cout<<"a";
}
if(T)cout<<endl;
}
return 0;
}
不是按二进制数增长的顺序
#include <iostream>
#include <algorithm>
using namespace std;
const int N=105;
int main(){
int T,n,k;
cin>>T;
while(T--){
cin>>n>>k;
int st=3;
st=st+k-1;
string s="";
while(st){
if(st&1)s+="b";
else s+="a";
st<<=1;
}
reverse(s.begin(),s.end());
cout<<s;
if(T)cout<<endl;
}
return 0;
}
最开始next_permutation,TLE
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
int t,n,k;
cin>>t;
while(t--){
cin>>n>>k;
string s="";
for(int i=1;i<=n-2;i++){
s+='a';
}
s+="bb";
if(k==1){
cout<<s;
if(t)cout<<endl;
continue;
}
k--;
while(next_permutation(s.begin(),s.end())){
if(k==1)break;
k--;
}
cout<<s;
if(t)cout<<endl;
}
return 0;
}