2022河南萌新联赛第(一)场:河南工业大学
A-Alice and Bob
给了一个数n,a和b每人每次可进行一次操作使n/x的k次方,谁除到1谁就输,a肯定不想让b赢(真苟),b也肯定不想让a赢(同样苟),每次只能除一个数的k次方,肯定就是分解质因数了,能分解成偶数个质因数,那么肯定是a赢,奇数个肯定是b赢。但是过了一半的数据,奇数个的时候,Alice姐真的甘愿放弃吗,事情会有转机的,如果是奇数个,Alice可以找一个次方为2的,让其变为偶数个,她就可以稳操胜局
1 #include<iostream> 2 using namespace std; 3 int main() 4 { 5 long long x; 6 int ans=0; 7 cin>>x; 8 int p=0; 9 for (int i = 2; i <= x/i; i ++ ) 10 { 11 if(x%i==0) 12 { 13 int t=0; 14 while(x%i==0) 15 { 16 x/=i; 17 t++; 18 } 19 ans++; 20 if(t>1) p++; 21 } 22 } 23 if(x>1) ans++; 24 if(ans%2==0) cout<<"Alice win"; 25 else 26 { 27 if(p) cout<<"Alice win"; 28 else cout<<"Bob win"; 29 } 30 return 0; 31 }
B-打对子
找对子比谁剩下的牌少,意思就是对子全部打完。记得要先排序。
1 #include<iostream>
2 #include<algorithm> 3 using namespace std; 4 const int N=1e6+10; 5 char a[N],b[N]; 6 int main() 7 { 8 int n; 9 cin>>n; 10 for(int i=0;i<n;i++) cin>>a[i]; 11 for(int i=0;i<n;i++) cin>>b[i]; 12 int x=0,y=0; 13 sort(a,a+n); 14 sort(b,b+n); 15 for(int i=1;i<n;i++) 16 { 17 if(a[i]==a[i-1]) 18 { 19 x++; 20 i++; 21 } 22 } 23 for(int i=1;i<n;i++) 24 { 25 if(b[i]==b[i-1]) 26 { 27 y++; 28 i++; 29 } 30 } 31 cout<<n-x*2<<endl; 32 if(x>y) cout<<"YES"<<endl; 33 else cout<<"NO"<<endl; 34 return 0;
给了一个队列,每个人的序号为初始每个人的位置,然后开始抽签,抽到谁谁就站到最后,抽m次看一看前5是谁。刚开始暴力果然TLE了,仔细一想抽签的话抽出来就无法再抽他了,那么我们的位置就和第几次把他抽出来有关。
1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 const int N=1e5+10; 5 bool st[N]; 6 int a[N]; 7 int main() 8 { 9 int n,m; 10 cin>>n>>m; 11 while(m--) 12 { 13 int x; 14 cin>>x; 15 a[n-m]=x; 16 st[x]=true; 17 } 18 int k=1; 19 for(int i=1;i<=n;i++) 20 { 21 if(!st[i]) 22 { 23 a[k]=i; 24 k++; 25 } 26 } 27 sort(a+1,a+1+5); 28 for(int i=1;i<=5;i++) 29 cout<<a[i]<<' '; 30 return 0; 31 }
F-买车
初始时给你一个电量t,能走t公里,然后中间有车店,车店能换车,一共有A个车店,每个车店的车能跑Ai公里,问能否跑到终点。
第一个思路:设走过的距离为s当前还能走的电量为t,先判断s+t是否大于等于终点,到不了,看能否到达最近的加油站当然t肯定得减去距离(当前点与加油站的距离)然后判断t与Ai谁大是否需要换车,最后直到到达终点或者半路就不走了。最后还是wa了,自始至终都没有考虑过一个因素就是,加油站的数量要尽可能的小,这真是个坑!!!
第二个思路就是,判断当前电量最多能走多远,走不动了,再返回去找电量给的最多的车店,p[i].first+p[i].second,第一个是车店离原点的距离,第二个是当前车店给的电量,加起来即是在如果在这个车店换车最多能走多远。为了使我们使用车店最少,我们每次选择能走的距离最大的,那么就是一个大根堆。何时选择,当我们的当前的距离到不了某个车站时,说明电量不够,需要更新。heap.size()&&heap.top()>=p[i].first当堆内有值且堆顶的值大于当前达不到的车店的距离,我们进行更新,如果不满足说明已经油尽灯枯了,到不了,退出循环返回-1即可。
特别注意:我们没有在循环中判定到终点的距离,那么就有一种情况就是所有车店都可到达,但是不知道能否到达终点,即没有进行,初始值就已经可以到达所有车店,所以我们还需要开一个特判,t<n的话,取堆顶 ans++,更新t,判断其值。
1 #include<iostream> 2 #include<queue> 3 #include<algorithm> 4 #include<vector> 5 using namespace std; 6 typedef pair<int,int> PII; 7 const int N=1e5+10; 8 PII p[N]; 9 int main() 10 { 11 int n,m,t; 12 cin>>n>>m>>t; 13 for(int i=0;i<m;i++) cin>>p[i].first>>p[i].second; 14 sort(p,p+m); 15 int ans=0; 16 priority_queue<int,vector<int>>heap; 17 for(int i=0;i<m;i++) 18 { 19 if(p[i].first>t)//当前的距离t达不到这个车店了 20 { 21 if(heap.size()&&heap.top()>=p[i].first) 22 { //找到堆定 即最远到的那个点判断是否必这个车店大 23 t=heap.top(); 24 heap.pop(); 25 ans++; 26 } 27 else { 28 cout<<-1<<endl; 29 return 0; 30 } 31 } 32 heap.push(p[i].first+p[i].second);//当t>p[i].first时 意思是当前的距离已经能到达这个车店。将这个车店的距离与在这个车店能走多远入队即可 33 } 34 if (t < n) 35 t = heap.top(), ans++; 36 if (t >= n) 37 cout << ans << endl; 38 else 39 cout << "-1" << endl; 40 return 0; 41 }
K-糟糕的一天
如果i>j,且a[i]>a[j]就说这个第j天也太糟糕了。意思就是只要他后面有比他大的就太糟糕了。那我们可以从后往前,找当前位的最大值吧b[i],如果a[i]>b[i]那么就更新,使得其对应的是后面的最大值。
1 #include<iostream> 2 using namespace std; 3 const int N=1e6+10; 4 long long a[N],b[N]; 5 int main() 6 { 7 int n; 8 cin>>n; 9 for(int i=0;i<n;i++) 10 cin>>a[i]; 11 int maxn=-0x3f3f3f3f; 12 for(int i=n-1;i>=0;i--) 13 { 14 if(a[i]>maxn) 15 { 16 maxn=a[i]; 17 } 18 b[i]=maxn; 19 } 20 int res=0; 21 for(int i=0;i<n;i++) 22 { 23 if(a[i]<b[i]) 24 res++; 25 } 26 cout<<res; 27 return 0; 28 }