比赛链接
A - September
题目及范围:
思路:
读入每一个字符串,判断字符串长度和当前字符串的出现的次序是否一致即可。
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <map>
#define int long long
#define endl '\n'
//
using namespace std;
int n,m,t,p,k,q;
int num[200005];
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
string s;
int cnt=0;
for(int i=1;cin>>s;i++){
if(s.length()==i) cnt++;
}
cout<<cnt<<endl;
}
B - 1D Keyboard
题目及范围:
思路:
暴力枚举当前要按的字母,每次遍历一边键盘。找到要按的字母和上一个字母的距离,累加一下输出。
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <map>
#define int long long
#define endl '\n'
//
using namespace std;
int n,m,t,p,k,q;
int num[27];
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
string s;
for(int i=1;i<=26;i++) num[i]=i;
cin>>s;
int cnt=0;
bool flag=false;
int lastj=0;
for(int i=0;i<26;i++){
for(int j=0;j<s.length();j++){
if((s[j]-'A')==i){
if(flag) {cnt+=abs(j-lastj),lastj=j;break;}
else {flag=true,lastj=j;break;}
}
}
}
cout<<cnt<<endl;
}
C - Max Ai+Bj
题目及范围:
思路:
遍历两个数组,找到两个数组中的最大值,相加直接输出即可。
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <map>
#define int long long
#define endl '\n'
//
using namespace std;
int n,m,t,p,k,q;
int num[27];
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>n;
int max1=-0x3f3f3f3f3f3f3f3f;
int max2=-0x3f3f3f3f3f3f3f3f;
for(int i=1;i<=n;i++){
int a;
cin>>a;
max1=max(max1,a);
}
for(int i=1;i<=n;i++){
int a;
cin>>a;
max2=max(max2,a);
}
cout<<max1+max2<<endl;
}
D - Hidden Weights
题目及范围:
思路:
依题意建图,但注意要建双向边。然后设起点为0,进行bfs。每搜索到一个点,就给这个点根据这个边的权值,赋予满足起点终点关系的权值。bfs每个点只会搜到一次,不用担心冲突。还有就是,考虑到这个图可能是非连通图,记得每个点为起点尝试bfs一遍。如果这个点从未访问过就以该点为起点搜索。保证每个点只会被访问一次。
复杂度
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <map>
#define int long long
#define endl '\n'
//
using namespace std;
int n,m,num_edge=0;
int head[2000005];
int val[2000005];
bool vis[2000005];
struct Edge{
int from,to,dis;
int next;
}edge[2000005];
void add(int from,int to,int dis){//建图
edge[++num_edge].from=from;
edge[num_edge].to=to;
edge[num_edge].dis=dis;
edge[num_edge].next=head[from];
head[from]=num_edge;
}
void bfs(int start){//bfs
queue<int> q;
vis[start]=true;
val[start]=0;
q.push(start);
while(!q.empty()){
int u=q.front();
//cout<<u<<"***"<<val[u]<<endl;
q.pop();
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(vis[v]==false){
vis[v]=true;
val[v]=val[u]+edge[i].dis;
q.push(v);
}
}
}
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++){
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);
add(b,a,-c);//一定要建双向边并且记得赋相反的权值。
}
for(int i=1;i<=n;i++){
if(vis[i]==false) bfs(i);//每个点都要记得尝试一遍
}
for(int i=1;i<=n;i++) cout<<val[i]<<" ";
}
E - How to Win the Election
题目及数据范围:
思路:
对每位候选者来说,拿到的票越多,越容易当选。这种具有单调性的问题考虑二分。
我们先排序以便计算。那么二分的check,实际上就是检查票数在除去当前候选人本身的前M个候选人,能不能全部达到这个临界票数。如果暴力处理M个人,那么复杂度为,超出题目的范围。所以直观考虑优化check的复杂度。
我们可以先给Ai加上mid。再看看它在原数组中的排位。用二分查找降低复杂度。再去判断,排名除了他自己的前M人中,排名比自己低的人,用上剩余的票能不能让排名超过自己。如果可以则自己无法当选,mid增加。反之mid减小。(因为排名比自己高的人不需要再拿剩余的票,所以贪心地给那些排名靠后的人就好了)
该操作用前缀和优化即可。
这个check操作的复杂度在二分查找。所以总复杂度在
代码:
以后再补。。