南外普及模拟赛
前言
想出了所有题正解,但是愉快挂掉 。
T1
给 个数,在 范围内选择一个 ,使得 个数除以 余数和最小。
。
直接暴力枚举。
得分 。
T2
给定一个数 。求最小的 使得 乘积后有 个 0。
思路也很简单,利用十进制中 。直接求出这两个质因子的个数。
然后看距离目标需要补多少个。这是赛时代码:
#include<bits/stdc++.h>
using namespace std;
int Q;
long long a,k,c2,c5;
int main() {
ios::sync_with_stdio(0); cin.tie(0), cout.tie(0);
cin>>Q;
while(Q--) {
c2=c5=0;
cin>>a>>k;
while(a%2==0) {
a/=2; c2++;
}
while(a%5==0) {
a/=5; c5++;
}
if(min(c2,c5)>=k) cout<<"1\n";
else {
long long p1=k-c2,q1=k-c5,p,q;
//p1,q1 小于 0 时,p,q UB
if(p1>=0) p=pow(2,p1);
if(q1>=0) q=pow(5,q1);
cout<<p*q<<"\n";
}
}
return 0;
}
这是没有分的,因为当目标与已有质因数差小于 0 时,没有赋初值!!!!
long long p1=k-c2,q1=k-c5,ans=1;
if(p1>=0) ans*=pow(2,p1);
if(q1>=0) ans*=pow(5,q1);
在使用 if 的时候,要考虑两种分支!
挂掉 。
T3
给定一个完全二叉树。每个点上有一个字符。统计有多少个点 ,使以 为根的子树的所有结点通过任意排列构成回文串。
然后进行 次修改,形如 x k。将点 修改为 。
考虑先搜索一遍,自下而上找到每个值是否合法。使用回文数的性质,如果在 a-z 中有 个的字符个数为奇数。就不合法。
对于修改,由于最多影响 个节点,直接暴力改掉。
复杂度 。
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
int n,m;
int c[N][30],ans,w[N],t[N];
char s;
void dfs(int from) {
if(from*2<=n) dfs(from*2);
if(from*2+1<=n) dfs(from*2+1);
int k=0;
for(int i=0;i<26;i++) {//from*2 越界
c[from][i]+=c[from*2][i]+c[from*2+1][i];
k+=c[from][i]&1;
}
if(k<2) ans++ ,t[from]=1;
}
void chg(int from,int x,int k) {
while(from) {
c[from][x]+=k;
int p=0;
for(int i=0;i<26;i++) p+=c[from][i]&1;
if(p>=2&&t[from]==1) ans--,t[from]=0;
if(p<2&&t[from]==0) ans++,t[from]=1;
from>>=1;
}
}
int main() {
ios::sync_with_stdio(0); cin.tie(0), cout.tie(0);
cin>>n>>m;
if(n>100000||m>100000) while(1);
for(int i=1;i<=n;i++) {
cin>>s;
c[i][s-'a']=1;
w[i]=s-'a';
}
dfs(1);
cout<<ans<<"\n";
while(m--) {
int x; char y;
cin>>x>>y;
chg(x,w[x],-1);
w[x]=y-'a';
chg(x,w[x],1);
cout<<ans<<"\n";
}
return 0;
}
由于数组越界,数组也只开了 ,挂掉了 。
解决方法:
- 把数组开到 。
- 加入判断,防越界。
T4
输入 , 为 的倍数。问满足长度为 的顺序对数量等于逆序对数量的字典序最小的序列。
需要足够的发散性思维。
显然长度为 的序列总共有 个对。而每个数都不相等,所以这些对不是顺序对就是逆序对。所以顺序对,逆序对都有 个。
我们可以对顺序对进行讨论。从贪心的角度看, 一定是最优的。但是这样就会使得顺序对过多。
当无法顺着选时,就找一个数,提供剩下的顺序对,使得顺序对数量达到 。
再选了这些数后,我们无法选其他的,所以倒序输出剩下的数。
因为字典序的性质,我们可以用贪心解决本题。推起来很简单,但是真的无从下手。对着全排列打的表看了一个小时...
#include<bits/stdc++.h>
using namespace std;
#define rint register unsigned int
unsigned int n;
long long taa,x;
int main() {
ios::sync_with_stdio(0); cin.tie(0), cout.tie(0);
cin>>n;
taa=n*(n-1LL)>>2;
for(rint i=1;i<=n;i++) {
if(x+n-i<=taa)
cout<<i<<" ",x+=n-i;
else {
cout<<n-(taa-x)<<" ";
for(rint j=n;j>=i;j--)
if(j^n-taa+x) cout<<j<<" ";
return 0;
}
}
return 0;
}

浙公网安备 33010602011771号