- 有问题联系QQ:2463973240
A:签到题
思路:直接if else判断就行或者一个map存下来直接输出更加方便
#include<iostream>
#include<map>
#define sis std::ios::sync_with_stdio(false)
#define sos cin.tie(0),cout.tie(0)
using namespace std;
map<int,string>mp;
int main()
{
sis,sos;
mp[1]="Higher mathematics",mp[2]="Linear algebra",mp[3]="Principle of computer composition";
mp[4]="Database system concept",mp[5]="Data structures and algorithms";
int n;cin>>n;
if(n>=1&&n<5)
cout<<"You were studying "<<mp[n]<<'!'<<endl;
else cout<<"You were playing games!"<<endl;
return 0;
}
B :签到题
思路:贪心想要支付的尽可能的少肯定优先支付五元的不超过五元的部分用一元的支付,要是五元的面值高于需要的直接输出,低于需要的输出五元的最大值然后输出总值减去五元 * 五元的个数,记得开long long
#include<iostream>
#define sis std::ios::sync_with_stdio(false)
#define sos cin.tie(0),cout.tie(0)
typedef long long ll;
using namespace std;
int main()
{
sis,sos;
ll n,m;cin>>n>>m;
ll m5=m/5,m1=m%5;
if(m5<=n)cout<<m5<<' '<<m1<<endl;
else
{
cout<<n<<' '<<m-n*5<<endl;
}
return 0;
}
C :博弈论
思路:发现四有特殊性如果是四的倍数先手不管拿几个后手一定会拿凑成四的倍数个这样一定是后手先赢,如果不是先手只需要先拿成四的倍数就好
#include<iostream>
#define sis std::ios::sync_with_stdio(false)
#define sos cin.tie(0),cout.tie(0)
using namespace std;
int main()
{
sis,sos;
int n;cin>>n;
if(n%4==0)puts("bob");
else puts("kiki");
return 0;
}
D :思维题
思路:写到这题就有种回到cf的感觉了,思维题写着是最有意思的,先计算左端点是n的多少倍上取整,再计算右端点是n的多少倍上取整,显然要是两个值都大于R,L,R都在某个k * n到(k+1) * n之间所以最大就是R%n另外一种情况是左端点除n的上取整在L到R之间这样是话跨越了两个n的倍数,答案自然就是n-1
#include<iostream>
using namespace std;
#define sis std::ios::sync_with_stdio(false)
#define sos cin.tie(0),cout.tie(0)
int main()
{
sis,sos;
int n,l,r;cin>>n>>l>>r;
int base=(l-1)/n+1;
int top=(r-1)/n+1;
if(base*n>=r)cout<<r%n<<endl;
else cout<<n-1<<endl;
return 0;
}
E :数学题
思路:有一定数学知识的都直到任何一个数都可以用二进制来表示,由于该题说的是2的正整数次幂,则任何偶数都能用2的正整数次幂来表示,从大到小循环输出就好,当前的i小于x则输出i,然后让x-i
#include<iostream>
#define sis std::ios::sync_with_stdio(false)
#define sos cin.tie(0),cout.tie(0)
using namespace std;
int main()
{
sis,sos;
int n;cin>>n;
if(n&1)cout<<-1<<endl;
else
{
for(int i=1<<30;i>=2;)
{
if(i<=n)
cout<<i<<' ',n-=i;
i>>=1;
if(!n)break;
}
}
cout<<endl;
}
F :字符串
思路:说他是个字符串也不完全是,因为更像一个思维,只需要双指针一个在前一个在后扫一遍,要是不相等直接添加小的就好,相等的话就两个指针一个往前一个往后依次找,直到出现不相等然后加上更小的那个所在指针的最前面或者最后面的字符,如果全相等加后面或者加前面都可以
#include<iostream>
#define sis std::ios::sync_with_stdio(false)
#define sos cin.tie(0),cout.tie(0)
using namespace std;
int main()
{
sis,sos;
int n;cin>>n;
string str;cin>>str;
string res;
int i=0,j=n-1;
while (i<=j)
{
if(str[i]<str[j])res+=str[i++];
else if(str[i]>str[j])res+=str[j--];
else
{
int l=i,r=j;
bool flag=true;
while (l<=r)
{
if(str[l]<str[r])break;
else if(str[l]>str[r])
{
flag=false;
break;
}
else l++,r--;
}
if(flag)res+=str[i++];
else res+=str[j--];
}
}
cout<<res<<endl;
return 0;
}
G :思维题
思路:首先这是cf原题,如果障碍电在两点之间则输出两点间的曼哈顿距离加2否则输出两点间的曼哈顿距离就行
#include<iostream>
#include<cmath>
#define sis std::ios::sync_with_stdio(false)
#define sos cin.tie(0),cout.tie(0)
using namespace std;
int main()
{
sis,sos;
int x1,y1,x2,y2,x3,y3;
int t;cin>>t;
while(t--)
{
int ans=0;
cin>>x1>>y1>>x2>>y2>>x3>>y3;
if ((x3==x1&&x3==x2&&y3<y2&&y3>y1)||(x3==x1&&x3==x2&&y3>y2&&y3<y1))
ans=fabs(x1-x2)+fabs(y1-y2)+2;
else if((y3==y1&&y3==y2&&x3<x2&&x3>x1)||(y3==y1&&y3==y2&&x3>x2&&x3<x1))
ans=fabs(x1-x2)+fabs(y1-y2)+2;
else ans=fabs(x1-x2)+fabs(y1-y2);
cout<<ans<<endl;
}
return 0;
}
H :思维题
思路:首先是洛谷原题,士兵过桥的问题,把弹性碰撞看成灵魂互换就好,最短时间就是大于中间点的像右滚小于中间点的向左滚的最大时间,最长时间就是小于中间点的向右滚大于中间点的向左滚的最大时间
#include<iostream>
#define sis std::ios::sync_with_stdio(false)
#define sos cin.tie(0),cout.tie(0)
using namespace std;
const int N=1e6+10;
int a[N],b[N];
int main()
{
sis,sos;
int L,n;
cin>>L>>n;
int ma1=0,ma2=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(a[i]>L/2)ma1=max(L-a[i],ma1);
else ma1=max(a[i],ma1);
if(a[i]>L/2)ma2=max(a[i],ma2);
else ma2=max(L-a[i],ma2);
}
cout<<ma1<<' '<<ma2<<endl;
return 0;
}
I :思维题
思路:只要上一个的最大值与计时器取max小于当前的最小值与而且就有当前最小值减去上一次最大值与计时器的max加一的重叠不清楚比分的区间,要是要平局最大当然就是把重叠的全看成平局,最后计时器等于当前最小值加一
#include<iostream>
#define sis std::ios::sync_with_stdio(false)
#define sos cin.tie(0),cout.tie(0)
using namespace std;
const int N=10010;
typedef pair<int,int>pii;
pii s[N];
int main()
{
sis,sos;
int n;cin>>n;
s[0]={0,0};
int ans=0,t=0;
for(int i=1;i<=n;i++)
{
cin>>s[i].first>>s[i].second;
int mi=max(s[i-1].first,s[i-1].second);
int ma=min(s[i].first,s[i].second);
mi=max(mi,t);
if(ma>=mi)
{
ans+=ma-mi+1;
t=ma+1;
}
}
cout<<ans<<endl;
return 0;
}
J :思维题
思路:每次往前跳的时候要是跳不到最近的一个直接跳出循环,能的话每次往后更新可以跳到的最大值,最后与最大长度取min防止跳出界
#include<iostream>
#define sis std::ios::sync_with_stdio(false)
#define sos cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
int main()
{
sis,sos;
ll n;cin>>n;
ll ans=1;
ll x;
for (ll i=1;i<=n;i++)
{
if (i>ans)break;// 跳不到最近的一个瓷砖直接跳出循环
cin>>x;
ans=max(ans,i+x);
}
cout<<min(ans,n)<<endl;
return 0;
}
K :字符串
思路:由于乘法优于加法肯定是连续的可以做乘的全部做乘,解释连续的含义JaykkJay里面含有两个连续的Jay,代表的是三个字符连在一起,不是很明白了现在,样例1的意思是倒置的Jay即yaJ也算是连续的,但是按照这种方法来写JayJJyyaayaJ的结果应该是8,但是AC代码的ans是6也就是说AC代码的连续的yaJ不算Jay,按照不算来看的话代码如下(一个快速幂搞定),知识点:char数组远远快于string
#include<iostream>
#include<cmath>
#include<cstring>
#define sis std::ios::sync_with_stdio(false)
#define sos cin.tie(0),cout.tie(0)
using namespace std;
const int mod=1e9+7;
typedef long long ll;
ll k,J,a,y;
char s[100000010];
ll qpow(ll a,ll k)
{
ll res=1;
while(k)
{
if(k&1)res=res*a%mod;
a=a*a%mod;
k>>=1;
}
return res;
}
int main()
{
sis,sos;
scanf("%s",s);
int len=strlen(s);
for(int i=0;i<len;i++)
{
if (s[i]=='J'&&s[i+1]=='a'&&s[i+2]=='y')
k++,i+=2;
else
{
if (s[i]=='J')J++;
else if(s[i]=='a')a++;
else if(s[i]=='y')y++;
}
}
ll base=min(J,min(a,y));
if(k==0)cout<<base<<endl;
else
{
if (!base) cout<<1ll*qpow(2,k-1)%mod<<endl;
else cout<<1ll*base*qpow(2,k)%mod<<endl;
}
return 0;
}