A:给定a,b输出a的b次方加上b的a次方。
因为代码的量很小,所以就是直接用pow计算然后转成int,就不会精度损失。
#include<bits/stdc++.h>
using namespace std;
using LL=long long;
int main(void){
int a,b;
cin>>a>>b;
cout<<int(pow(a,b)+pow(b,a))<<endl;
}
B:
给定一个字符串,求出长度最长的回文串。
因为长度只有100,可以直接枚举子串,然后暴力判断是不是回文串,就是反转之后是否和自身相同,复杂度为O(n).数据范围够大的话,可以用Manachar算法O(n)。Manacher算法的作用就是在O(N)的时间复杂度下求出以每个位置为回文中心的回文半径。
#include<bits/stdc++.h>
using namespace std;
using LL=long long;
int main(void){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
string s;
cin>>s;
int ans=0;
auto ok=[&](int l,int r){
string a= s.substr(l,r-l+1);
string b=a;
reverse(b.begin(),b.end());
return a==b;
};
for(int i=0;i<s.size();i++)
{
for(int j=i;j<s.size();j++)
{
if(ok(i,j))
ans=max(ans,j-i+1);
}
}
cout<<ans<<endl;
}
C:题目大意:
给定n=3排灯,以及三个长度都为m的数字串,表示每一时刻,每盏灯依次循环地展示这些数字。对于某一个时刻,你最只能够按一个按钮,从而让一盏灯停下来,当然,你可以什么都不操作。问最终让三盏灯停下来时显示的数字都一样,需要的最短时间。
思路:就是最简单的暴力思路,枚举最终情况,显示的数字是什么,有10种情况。然后考虑这三排灯按按钮的顺序,同样枚举这个顺序,有3!种情况。也就是遇到了这个数字,先是谁去停下来。
最终确定了数字和按按钮的顺序,剩下的就是模拟,只看一盏灯,然后出现这个数字时候,就按按钮,时间复杂度是O(m)。最终的复杂度就是(n!*10*n*m);
iota函数对一个范围数据进行赋值:
这里的赋值,就是按照初始值,一步步的增长去赋值的。
template <class ForwardIterator, class T>
void iota (ForwardIterator first, ForwardIterator last, T val)
{
while (first!=last) {
*first = val;
++first;
++val;
}
}
#include<bits/stdc++.h>
using namespace std;
using LL=long long;
const int inf=1e9;
int main(void){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int m;
cin>>m;
array<string,3>s;
for(auto& i:s)
cin>>i;
int ans=1e9;
for(int i=0;i<=9;i++)
{
array<int,3>id{};
iota(id.begin(),id.end(),0);
do{
int cur=0;
int tot=0;
for(auto&j :id){
if(s[j].find(i+'0')==string::npos){
tot=inf;
break;
}
while(s[j][cur]-'0'!=i){//当恰恰好循环到了这个数字,就停止了继续循环
cur=(cur+1)%m;
++tot;
}
cur=(cur+1)%m; //这个时候说明了下去往下找位置。如说超过了m在往回来找。
++tot;
}
ans=min(ans,tot);
}while(next_permutation(id.begin(),id.end()));
}
if(ans==inf) ans=0;
cout<<ans-1<<endl;
}
D:
二维平面,有n个人,其中第一个人在原点。给定m条信息(a,b,x,y),表示第b个人的位置是ax+x,ay+y,其中ax和ay表示就是第a个人的位置。问每个人的位置,或者告知不确定。
思路:初始只知道一个人的位置是确定的,那么所有与第一个人相关的信息的其他人的位置都能确定。有更多的人的位置确定了,那么与这些人相关的信息的更多的人的位置都可以确定。这就跟一个关系网一样,从第一个人往外传播,遍及能够到的人。这就是一张图,我们根据这些信息建立一张无向图,从1号点开始BFS,确定中间每个人的位置。没有遍历到的点就是不确定的人。
#include<bits/stdc++.h>
using namespace std;
using LL=long long;
const int inf=1e9;
int main(void){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,m;
cin>>n>>m;
vector<vector<array<int,3>>>edge(n);
for(int i=0;i<m;i++){
int a,b,x,y;
--a,--b;
edge[a].push_back({b,x,y});
edge[b].push_back({a,-x,-y});
}
queue<int>team;
vector<int>ok(n);
vector<array<LL,2>>pos(n,{0,0});
ok[0]=1;
team.push(0);
while(!team.empty()){
auto u =team.front();
team.pop();
for(auto& [v,x,y]:edge[u]){
if(!ok[v]){
pos[v]={pos[u][0]+x,pos[u][1]+y};
ok[v]=1;
team.push(v);
}
}
}
for(int i=0;i<n;i++){
if(ok[i])
{
cout<<pos[i][0]<<' '<<pos[i][1]<<'\n';
}
else cout<<"undecidable"<<'\n';
}
return 0;
}
E:
给定n个人,从左到右,有q个事件,每个事件就如(t,w,s),表示的是第t时刻,当前最左边的人可以获得w的分数然后离开,直到t+s时刻回来。问最后每一个的分数。
思路:就是说,去计算每一个时刻,但时刻最高可以达到1e9,主要到很多时刻就是没有事情发生的。那么只用考虑会发生时间的时刻就可以了。
#include<bits/stdc++.h>
using namespace std;
using LL=long long;
int main(void){
int n,m;
cin>>n>>m;
priority_queue<int>team; //默认的是大顶堆,就是从大到小的进行排序。
for(int i=0;i<n;i++){
team.push(-i);
}
priority_queue<array<int,2>>event;
vector<LL>ans(n);
for(int i=0;i<m;i++){
int t,w,s;
cin>>t>>w>>s;
while(!event.empty()&&-event.top()[0]<=t){
auto[_,u]=event.top();
event.pop();
team.push(-u);
}
//如果说在t时刻之间,序号优先级在前面的人已经回来了,那么就会按照优先级去排序,每次只能够对一个去加分。
if(!team.empty()){
int u=-team.top();
team.pop();
ans[u]+=w;
event.push({-(t+s),u});
}
}
for(auto&i :ans){
cout<<i<<'\n';
}
}