- A题:
找规律,用快速幂算一下(2^n/2+1)-2就行了,代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int quickmi(int a,int b)
{
int ans=1,base=a;
while(b>0)
{
if(b&1)
{
ans*=base;
}
base*=base;
b>>=1;
}
return ans;
}
int main()
{
int t,n,ans;
cin>>t;
while(t--)
{
cin>>n;
ans=quickmi(2,n/2+1)-2;
cout<<ans<<endl;
}
return 0;
}
- B题:
设difference代表给出数组不同值的个数,刚开始WA了三次,原因是没考虑最简单的情况difference<k。
题解是用两个数组去重,我是用的set,因为set里面不会存取重复的值。
思路:
difference>k输出-1;
否则将给出数组中的不同值存入set中,对于数组中的每一个值替换为k个数,这k个数是set中的数循环输出。
代码如下:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t,n,k,i,j;
set<int>h;
set<int>::iterator p;
cin>>t;
while(t--)
{
h.clear();
cin>>n>>k;
int a[100+8];
for(i=0; i<n; i++)
{
cin>>a[i];
h.insert(a[i]);
}
int difference=0;
difference=h.size();
//cout<<difference<<endl;
if(difference>k)
{
cout<<"-1"<<endl;
}
else
{
cout<<n*k<<endl;
for(i=0; i<n; i++)
{
int flag=0;
p=h.begin();
while(1)
{
if(flag==k)
{
break;
}
if(p==h.end())
{
p=h.begin();
}
cout<<*p<<' ';
p++;
flag++;
}
}
cout<<endl;
}
}
return 0;
}
- C题:
WA了三次,原因是用了int和float,后来仔细一想发现原来可以把乘法变成除法。
思路很简单,就是比较两种方法-1所消耗的钱数,即比较a和b/2的大小,转换一下就是比较2*a和b的大小。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int quickmi(int a,int b)
{
int ans=1,base=a;
while(b>0)
{
if(b&1)
{
ans*=base;
}
base*=base;
b>>=1;
}
return ans;
}
int main()
{
int t,n,m,i,j,k;
int x,y;
int a,b;
cin>>t;
while(t--)
{
cin>>x>>y;
cin>>a>>b;
int ma=max(x,y);
int mi=min(x,y);
long long sum=0;
if(2*a>b)
{
sum+=(ll)mi*(ll)b+(ll)(ma-mi)*a;
}
else
{
sum+=((ll)x+(ll)y)*(ll)a;
}
cout<<sum<<endl;
}
return 0;
}
- D题:
分两种情况,第一种就是字符串全为1或全为0,此时直接输出该字符串就行,周期为1.
第二种就是既有0又有1,这时候就要把0和1相间输出,使得周期为2;
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int quickmi(int a,int b)
{
int ans=1,base=a;
while(b>0)
{
if(b&1)
{
ans*=base;
}
base*=base;
b>>=1;
}
return ans;
}
int main()
{
string s;
int t,i,j,k,n,m;
cin>>t;
while(t--)
{
cin>>s;
size_t f=s.find("1");
size_t p=s.find("0");
if(f==s.npos||p==s.npos)
{
cout<<s;
}
else
{
int len=s.size();
for(i=0;i<len-1;i++)
{
cout<<s[i];
if(s[i]==s[i+1])
{
if(s[i]=='0')
{
cout<<'1';
}
else
{
cout<<'0';
}
}
}
cout<<s[len-1];
}
cout<<endl;
}
return 0;
}
- E题:
没有技术含量的模拟题,完全根据题以来做就行。代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int quickmi(int a,int b)
{
int ans=1,base=a;
while(b>0)
{
if(b&1)
{
ans*=base;
}
base*=base;
b>>=1;
}
return ans;
}
int main()
{
int n,a,b,c,d,t;
cin>>t;
while(t--)
{
cin>>n>>a>>b>>c>>d;
if((a-b)*n>(c+d)||(a+b)*n<(c-d))
{
cout<<"No"<<endl;
continue;
}
cout<<"Yes"<<endl;
}
return 0;
}
- F题:
我原来的思路是先把每个峰的标号记录下来,然后根据标号的差和峰的个数找符合题意的值,后来发现无法实现。
正确思路:先记录每个山是否是峰,是为1,然后前缀和,求出每一段的峰值,然后判断边界是否为峰,是的话峰值-1,最后输出峰值的最大值以及所对应的左端点。
中间WA了两次是因为,没有考虑a[1]>a[0],和没有峰的情况。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[200000+8]={0},b[200000+8];
int flag[200000+8]={0};
int main()
{
int t,n,k,i,j,m;
cin>>t;
while(t--)
{
memset(flag,0,sizeof(flag));
cin>>n>>k;
for(i=1;i<=n;i++)
{
cin>>a[i];
}
a[0]=a[1]+1;
a[n+1]=a[n]+1;
for(i=2;i<n;i++)
{
if(a[i]>a[i-1]&&a[i]>a[i+1])
{
flag[i]=1;
}
}
int ma=-1,ans=0,sum=0;
for(i=1;i<=n;i++)
{
flag[i]+=flag[i-1];
}
for(i=1;i<n;i++)
{
if(i+k-1>n)
{
break;
}
sum=flag[i+k-1]-flag[i-1];
if(a[i]>a[i+1]&&a[i]>a[i-1])
{
sum--;
}
if(a[i+k-1]>a[i+k]&&a[i+k-1]>a[i+k-2])
{
sum--;
}
if(sum>ma)
{
ma=sum;
ans=i;
}
}
cout<<ma+1<<' '<<ans<<endl;
}
return 0;
}