大一限时训练题解
A - Happy New Year!

官方题解:
Let’s enumerate the integers that satisfy the condition.
2 20 22 200 202 220 222 2000 2002 2020 2022 ...

(其实就是把十进制换成二进制...............)这题我看你们正确率挺高的,差不多只要你们提交了代码(看出了二进制),结果基本上都是对的。
#include <iostream>
using namespace std;
int ans[64];
int main()
{
long long int t;
cin>>t;
int flag=0;
while(t){
if(t&1){
ans[flag++]=2;
}
else{
ans[flag++]=0;
}
t=t>>1;
}
for(int i=flag-1;i>=0;i--){//别忘了,要倒序输出来答案
cout<<ans[i];
}
cout<<endl;
return 0;
}
B - 抱抱熊的RGB气球

给你一个字符串,怎么样才能尽可能少地更换其中一些字符使这个字符串相邻的字符没有相同的,输出最少的更换次数。
#include <iostream>
#include <string>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--){
string s;
cin>>s;
int flag=0,sum=0;//sum统计的是更换次数
for(int i=0;i<s.length();i++){
if(i==0){
flag=1;
}
else{
if(s[i]==s[i-1]){
flag++;
}
else{
sum+=flag/2;
flag=1;
}
}
}
sum+=flag/2;//别忘了,最后那一串互相相邻且相同的子串还没有考虑
cout<<sum<<endl;
}
return 0;
}
C - 排列的最大值和

这题,对于你们来说应该挺难的,但是没有一个人做出来,这很不应该,列一个有序a序列,然后交换次序,观察sum的值,你们应该能做出来。
然后写两个“指针”(此指针非彼指针),通过指针移动,交换序列中的元素,得到b序列。
#include <iostream>
#include <cstdio>
using namespace std;
int ans[100005];//存放序列a
int num[100005];//存放1....n序列交换后的序列
int main()
{
//std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int t;
//cin>>t;
scanf("%d",&t);
while(t--){
long long int n;//这里要用long long定义n,否则n*(n+1)/2中途会爆掉
long long int sum;
//cin>>n>>sum;
scanf("%lld%lld",&n,&sum);
for(int i=1;i<=n;i++){
//cin>>ans[i];
scanf("%d",&ans[i]);
num[i]=i;
}
long long int summin=n*(n+1)/2;//sum的最小可能的值
long long int ext=sum-summin;//ext存放的是差值,后面的循环判断要用到这个差值
long long int flagi=1,flagj=n;//两个指针
while(ext){//当差值不为0的时候,进入循环
if(ext<=flagj-flagi){//每次循环利用的ext是否小于等于允许的的最大差值
swap(num[flagi],num[flagi+ext]);//如果小于等于,就交换应该交换的两个num存的值
ext=0;//这种情况满足以后,就不用再进行循环了,所以要把ext置为0
}
else{
swap(num[flagi],num[flagj]);//如果ext要大于每次循环允许的差值,就在移动两端指针之前,交换两端指针所在位置num所存的值
ext-=flagj-flagi; //同时更新差值
flagi++;
flagj--;
}
}
for(int i=1;i<=n;i++){
if(i==1){
//cout<<ans[num[i]];
printf("%d",num[ans[i]]);
}
else{
//cout<<" "<<ans[num[i]];
printf(" %d",num[ans[i]]);
}
}
//cout<<endl;
printf("\n");
}
return 0;
}
稍微改变了一下输入输出方式(少定义一个数组):
#include <iostream>
#include <cstdio>
using namespace std;
long long int ans[100005];
long long fun(long long n)
{
return n*(n+1)/2;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
int n;
long long int sum;
scanf("%d%lld",&n,&sum);
for(int i=1;i<=n;i++){
ans[i]=i;
}
long long int mi=fun(n);
long long int ext=sum-mi;
long long int flagj=n;
long long int flagi=1;
while(ext){
if(ext<=flagj-flagi){
swap(ans[flagi],ans[flagi+ext]);
ext=0;
}
else{
swap(ans[flagi],ans[flagj]);
ext-=flagj-flagi;
flagi++;
flagj--;
}
}
int h;
for(int j=1;j<=n;j++){
scanf("%d",&h);
if(j==1){
printf("%d",ans[h]);
}
else{
printf(" %d",ans[h]);
}
}
printf("\n");
}
return 0;
}

浙公网安备 33010602011771号