A题:A-Alice and Bob_2022河南萌新联赛第(一)场:河南工业大学 (nowcoder.com)
关键词:质因数分解(以质数分堆),博弈论(尼姆游戏),异或运算
Alice赢的情况:1.每一堆都为1,且为偶数堆;2.存在一堆不为1,且是奇数堆
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
ll n,c=0,ans=0;
cin>>n;
for(ll i=2;i*i<=n;i++)
{
if(n%i==0)
{
ll cnt=0;//临时标记这一堆有多少石子
while(n%i==0)
n/=i,cnt++;
if(cnt>1)//超过1就标记
c=1;
ans^=cnt;//计算堆值,判断奇偶
}
}
if(n>1)ans^=1;//n为质数
if((ans==0&&c==0)||(ans>0&&c==1))
puts("Alice win");
else puts("Bob win");
}
B题:B-打对子_2022河南萌新联赛第(一)场:河南工业大学 (nowcoder.com)
利用异或运算判断每个字符出现的次数为奇数次还是偶次,剩余的牌的数量==出现奇数次字符的和.
#include<bits/stdc++.h>
using namespace std;
int x[26],y[26];//存26个字母,0为偶次,1为奇数次
int main()
{
int n;
string a,b;
cin>>n>>a>>b;
for(int i=0;i<n;i++)
{
x[a[i]-'A']^=1;
y[b[i]-'A']^=1;
}
int c=0,d=0;
for(int i=0;i<26;i++)
{
c+=x[i];
d+=y[i];
}
if(c<d){cout<<c<<endl;puts("YES");}
else cout<<c<<endl,puts("NO");
}
C题:C-割竿榄_2022河南萌新联赛第(一)场:河南工业大学 (nowcoder.com)
关键词:数据范围long long,前缀和,
解决本题需要分三种情况:1,不能割遍整个田野的情况;2,能割遍且无重叠的情况;3,能割遍有重叠的情况。
针对第二种情况,首先把原有全部的竿揽总和到答案中,然后计算(除最后一遍割遍田野的次数)的生长值加入答案,最后再把最后一遍的生长值加入(此时会割光为0);
针对第一种情况,利用前缀和,计算能割到范围的最大值,最后再加上生长值。
#include<bits/stdc++.h>
using namespace std;
int b[200005];
long long s[200005];//注意防int爆炸
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>b[i];
s[i]=s[i-1]+b[i];//前缀和
}
long long ans=0;
if(3*m>n)//能割遍的情况
{
if(n%3==0)//能刚好割遍
{
ans=s[n];
ans+=1ll*(m-n/3)*n;
for(int i=0;i<n/3;i++)
ans+=i*3;//最后一次割遍
}
else //有重叠
{
ans=s[n]-1;
//有一个不能割为0(非重叠部分)或者有一个割为0后不生长(重叠部分)
ans+=1ll*(m-(n+2)/3)*n;//(n+2)/3为最后一次割所需要的次数
for(int i=0;i<(n+2)/3;i++)
ans+=i*3;
}
}
else //不能割遍
{
for(int i=1,j=3*m;j<=n;i++,j++)
ans=max(ans,(s[j]-s[i-1]));
for(int i=0;i<m;i++)
ans+=i*3;
}
cout<<ans<<endl;
}
D题:D-纪念品领取_2022河南萌新联赛第(一)场:河南工业大学 (nowcoder.com)
利用结构体,分别对每个人的编号,排队位置赋初值,按题意操作后,对其进行两次排序,一次为确定前五的位置,另一次为为前五按编号递增序号排序,最后按顺序输出就好啦。
#include<bits/stdc++.h>
using namespace std;
struct node
{
int c,num;
}t[200005];
bool cmp(node x,node y)
{
return x.num<y.num;
}
bool cmp1(node x,node y)
{
return x.c<y.c;
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
t[i].c=i;
t[i].num=i;
}
int j=n;
for(int i=1;i<=m;i++)
{
int x;
cin>>x;
t[x].num=++j;
}
sort(t+1,t+1+n,cmp);
sort(t+1,t+5+1,cmp1);//对前5排序
for(int i=1;i<=5;i++)
cout<<t[i].c<<" ";
}
E题:https://ac.nowcoder.com/acm/contest/37160/E
本题要点:1、排序;2、利用res来检查需要出现的值
#include<bits/stdc++.h>
using namespace std;
long long b[200005];
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>b[i];
sort(b,b+n);
long long res=1;
for(int i=0;i<n;i++)
{
if(res<b[i]){cout<<res;return 0;}//当需出现的值未出现,此时res为结果
else if(res>=b[i])
{
res+=b[i];//全集和的下一个数
}
}
cout<<res;
return 0;
}
F题:https://ac.nowcoder.com/acm/contest/37160/F
贪心,从最远可达点去选择最靠前的买车地。
#include<bits/stdc++.h>
using namespace std;
struct node
{
int a,b,c;
}t[200005];
bool cmp(node x,node y)
{
return x.c<y.c;
}
int main()
{
int n,m,k;
cin>>n>>m>>k;
t[0].a=0,t[0].b=k,t[0].c=k;
for(int i=1;i<=m;i++)
{
cin>>t[i].a>>t[i].b;
t[i].c=t[i].a+t[i].b;
}
sort(t,t+m+1,cmp);
int res=n,cnt=0;
while(res)
{
int p=0;
int temp=INT_MAX;
for(int i=0;i<m+1;i++)
if(t[i].c>=res&&t[i].a<res)
if(temp>t[i].a)temp=t[i].a,p=1;
if(p==0){puts("-1");return 0;}
res=temp,cnt++;
}
cout<<cnt-1;
}
K题:K-糟糕的一天_2022河南萌新联赛第(一)场:河南工业大学 (nowcoder.com)
签到题,看后面有没有比它大的数就行
#include<bits/stdc++.h>
using namespace std;
int b[1000005];
int main()
{
int n,ans=0;
cin>>n;
for(int i=1;i<=n;i++)
cin>>b[i];
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(b[i]<b[j])
{
ans++;break;
}
}
}
cout<<ans<<endl;
}
欠四题,完。