[2022河南萌新联赛第(四)场:郑州轻工业大学_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ (nowcoder.com)](https://ac.nowcoder.com/acm/contest/38487)

2022河南萌新联赛第(四)场:郑州轻工业大学ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛牛客竞赛OJ (nowcoder.com)

1.A-ZZULI_2022河南萌新联赛第(四)场:郑州轻工业大学 (nowcoder.com)

就是一个简单的并查集,考虑合并就好了没啥思维量。

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define fel(i,x,y) for(int i=x;i<=y;i++)
#define fhl(i,x,y) for(int i=x;i>=y;i--)
#define inf 0x3fffffff
#define ll long long
#define pb push_back
#define endl "\n"
//感觉就是找最前面四个字符zuli的最大连通块
const int N=1e6+100;
string s;
int p[N];
int find(int x){
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
map<int,int>mp;
int main(){
cin>>s;
int l=s.length();
int pos=l+1;
for(int i=0;i<l;i++) p[i]=i;
for(int i=0;i<l;i++){
if(s[i]=='Z'){
pos=i;
break;
}
}
for(int i=pos+1;i<l;i++){
if(s[i]=='Z'||s[i]=='U'||s[i]=='L'||s[i]=='I'){
if(find(pos)!=find(i)){
p[find(i)]=p[find(pos)];
}
}
}
pos=l+1;
for(int i=0;i<l;i++){
if(s[i]=='U'){
pos=i;
break;
}
}
for(int i=pos+1;i<l;i++){
if(s[i]=='U'||s[i]=='L'||s[i]=='I'){
if(find(pos)!=find(i)){
if(find(i)!=i){
p[find(pos)]=p[find(i)];
}
else{
p[find(i)]=p[find(pos)];
}
}
}
}
pos=l+1;
for(int i=0;i<l;i++){
if(s[i]=='L'){
pos=i;
break;
}
}
for(int i=pos+1;i<l;i++){
if(s[i]=='L'||s[i]=='I'){
if(find(pos)!=find(i)){
if(find(i)!=i){
p[find(pos)]=p[find(i)];
}
else{
p[find(i)]=p[find(pos)];
}
}
}
}
pos=l+1;
for(int i=0;i<l;i++){
if(s[i]=='I'){
pos=i;
break;
}
}
for(int i=pos+1;i<l;i++){
if(s[i]=='I'){
if(find(pos)!=find(i)){
if(find(i)!=i){
p[find(pos)]=p[find(i)];
}
else{
p[find(i)]=p[find(pos)];
}
}
}
}
for(int i=0;i<l;i++){
mp[find(i)]++;
}
int ans=0;
for(auto[x,y]:mp){
ans=max(y,ans);
}
cout<<ans<<endl;
return 0;
}

 

2.C-最大公因数_2022河南萌新联赛第(四)场:郑州轻工业大学 (nowcoder.com)

就是求一个区间内的是否有两个a,b满足gcd(a,b)==x.

我分了两种情况讨论,第一种是x=1,这就直接找到一个素数,然后再输出他的下一位就好了

第二种情况就是是否存在x的两个不相同的倍数在区间内。我们取的是cnt和cnt+1.如果存在就直接输出就好

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define fel(i,x,y) for(int i=x;i<=y;i++)
#define fhl(i,x,y) for(int i=x;i>=y;i--)
#define inf 0x3fffffff
#define ll long long
#define pb push_back
#define endl "\n"
ll l,r,x;
bool judge(int n){
if(n==1) return false;
int flag=1;
for(int i=2;i*i<=n;i++){
if(n%i==0){
flag=0;
break;
}
}
if(flag){
return true;
}
return false;
}
void slove(){
cin>>l>>r>>x;
if(x==1){
for(int i=l;i<r;i++){
if(judge(i)){
cout<<i<<" "<<i+1<<" ";
break;
}
}
return;
}
int cnt=l/x;
ll ans1=cnt*x;
ll ans2=x*(cnt+1);
while(ans2<=r){
if(ans1>=l&&ans2<=r){
cout<<ans1<<" "<<ans2<<endl;
return;
}
cnt++;
ans1=x*cnt;
ans2=x*(cnt+1);
}
cout<<-1<<endl;
}
int main(){
int t;
cin>>t;
while(t--){
slove();
}
return 0;
}

 

3.E-睡大觉_2022河南萌新联赛第(四)场:郑州轻工业大学 (nowcoder.com)

模拟题。如果下一个时间是第二天的话,那他肯定是小于第一个时间的。最开始记得考虑00:00:00的情况。如果第一个时间是00:00:00的话算是第二天,因为至少是睡一秒的。

然后唯一的特殊情况就是考虑闰年的二月。

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define fel(i,x,y) for(int i=x;i<=y;i++)
#define fhl(i,x,y) for(int i=x;i>=y;i--)
#define inf 0x3fffffff
#define ll long long
#define pb push_back
#define endl "\n"
string s,te2;
string te1="00:00:00";
int y,m,d,q;
int mm[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
ll ans;
int main(){
cin>>s;
y=(s[0]-'0')*1000+(s[1]-'0')*100+(s[2]-'0')*10+(s[3]-'0')*1;
m=(s[5]-'0')*10+s[6]-'0';
d=(s[8]-'0')*10+s[9]-'0';
cin>>q;
while(q--){
cin>>te2;
if(te2<=te1)d++;
te1=te2;
       int flag=0;
if(y%400==0||(y%4==0&&y%100!=0)){//如果是闰年
if(m==2){
               flag=1;
if(d>29){
m++;
d=1;
}
}
}
if(d>mm[m]&&flag==0){
d=1;
m++;
}
if(m>=13){
y++;
m=1;
}
if(m%2==d%2) ans++;
}
cout<<ans;
return 0;
}

 

4.G-迷宫_2022河南萌新联赛第(四)场:郑州轻工业大学 (nowcoder.com)

BFS优先队列优化一下就好,板子题。

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define fel(i,x,y) for(int i=x;i<=y;i++)
#define fhl(i,x,y) for(int i=x;i>=y;i--)
#define inf 0x3fffffff
#define ll long long
#define pb push_back
#define endl "\n"
const int N=2e3+10;
int n,m,ans=inf;
char mp[N][N];
bool vis[N][N];
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
struct node{
int x,y,w;
bool operator<(const node&x)const{
return x.w<w;
}
};
//感觉就是很bfs的题
//吃花可以让时间减少一
bool check(int x,int y){
if(x>=1&&x<=n&&y>=1&&y<=m&&!vis[x][y]&&mp[x][y]!='#'){
return true;
}
return false;
}
void bfs(){
priority_queue<node>q;
vis[1][1]=1;
q.push({1,1,0});
while(!q.empty()){
auto [x,y,w]=q.top();
q.pop();
if(x==n&&y==m){
cout<<w;
return;
}
for(int i=0;i<4;i++){
int nx=dx[i]+x;
int ny=dy[i]+y;
if(check(nx,ny)){
vis[nx][ny]=1;
if(mp[nx][ny]=='.'){
q.push({nx,ny,w+1});
}
if(mp[nx][ny]=='*'){
q.push({nx,ny,w});
}
}
}
}
cout<<-1;
}
int main(){
cin>>n>>m;
fel(i,1,n){
fel(j,1,m){
cin>>mp[i][j];
}
}
bfs();
return 0;
}

 

5.I-密集_2022河南萌新联赛第(四)场:郑州轻工业大学 (nowcoder.com)

这因该是比较明显的二分。二分时间,然后check这个时间的蜗牛数量是否可以可以小于k个。

check函数就考虑记录一下最开始坐标考前的能跑的最远是多少。如果后面的点跑的没有他远的话,就被他淘汰了,如果跑的比他还远就更新一下最远点。

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define fel(i,x,y) for(int i=x;i<=y;i++)
#define fhl(i,x,y) for(int i=x;i>=y;i--)
#define inf 0x3fffffff
#define ll long long
#define pb push_back
#define endl "\n"
const int N=1e5+100;
int n,k;
struct node{
ll p,v,id;
}pg[N];
bool cmp(node a,node b){
return a.p<b.p;
}
bool check(int x){
int ans=0;
ll ma=pg[1].p+pg[1].v*x;
for(int i=2;i<=n;i++){//记录一下能跑的最远距离就好
if(ma>pg[i].p+pg[i].v*x) ans++;
else ma=pg[i].p+pg[i].v*x;
}
return n-ans<=k;
}
int main(){
cin>>n>>k;
fel(i,1,n){
cin>>pg[i].p;
}
fel(i,1,n){
cin>>pg[i].v;
}
sort(pg+1,pg+1+n,cmp);
int l=1,r=1e9;
int ans=0;
while(l<=r){
int  mid=l+r>>1;
if(check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
if(check(ans)) cout<<ans<<endl;
else cout<<"Never!"<<endl;
return 0;
}

 

6.K-试稥_2022河南萌新联赛第(四)场:郑州轻工业大学 (nowcoder.com)

题目的意思大概就是能不能用题目所给的数任意选择最后异或和的值是x。而且给的条件是数组所给值是2的n次方。

那就很好办了,只要考虑是否再x的二进制每个为1的位上,我都能从数组中找到。这样最后的异或和就是x了.

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define fel(i,x,y) for(int i=x;i<=y;i++)
#define fhl(i,x,y) for(int i=x;i>=y;i--)
#define inf 0x3fffffff
#define ll long long
#define pb push_back
#define endl "\n"
ll n,a[110],x;
void slove(){
cin>>n>>x;
fel(i,1,n){
cin>>a[i];
}
vector<int>ans;
int t=0;
for(int i=0;i<=63;i++){
if((x>>i)&1) t++;
}
ll cnt=1;
while(x){
if(x&1){
for(int i=1;i<=n;i++){
if(a[i]==cnt){
ans.pb(i);
break;
}
}
}
x>>=1;
cnt*=2;
}
if(ans.size()==t){
cout<<t<<endl;
for(auto i:ans){
cout<<i<<" ";
}
cout<<endl;
}
else{
cout<<-1<<endl;
}
}
int main(){
int t;
cin>>t;
while(t--){
slove();
}
return 0;
}

 

7.L-固执_2022河南萌新联赛第(四)场:郑州轻工业大学 (nowcoder.com)

题意是给你一个字符串保证你无论如何重新排列这个字符串都还会存在一个位置与原字符串相等。这样的字符串称为固执串。然后给你一串字符串是否可以使他排列之后所有的后缀都是固执串。

要保证这样,很容易证明某一个字母的个数必须是要再1/2以上的(每一个后缀都必须保证)。同时要保证字典序最小。那我就考虑z开始加。最后给字符串reverse一下就可以了。

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define fel(i,x,y) for(int i=x;i<=y;i++)
#define fhl(i,x,y) for(int i=x;i>=y;i--)
#define inf 0x3fffffff
#define ll long long
#define pb push_back
#define endl "\n"
//只要我同一个字符占到了二分之一以上我就肯定是的
string s,ans;
int vis[26],n;
void add(int pos){
char x='a'+pos;
ans=ans+x;
}
int main(){
   IOS
   cin>>n;
cin>>s;
for(auto i:s){
vis[i-'a']++;
}
int pos=0;
for(int i=0;i<26;i++){
if(vis[i]>vis[pos]){
pos=i;
}
}
if(vis[pos]<=n/2){
cout<<"NO"<<endl;
}
else{
cout<<"YES"<<endl;
add(pos);
       vis[pos]--;
for(int i=25;i>=0;i--){
while(vis[i]){
if(vis[pos]&&i!=pos){
add(pos);
vis[pos]--;
}
if(vis[i]){
add(i);
vis[i]--;
}
}
}
while(vis[pos]){
           add(pos);
           vis[pos]--;
      }
       reverse(ans.begin(),ans.end());
cout<<ans<<endl;
}
return 0;
}
 
posted @ 2022-08-04 23:15  silky__player  阅读(90)  评论(0)    收藏  举报