ps: 因为训练 ,晚上在家做的
目录
· 比赛概况
T1 | T2 | T3 | T4 |
第二题敲出了用桶的正解 ,但是怕超时改成了C语言输入输出 ,结果输入变量改错了 ,没重新跑样例 ,看编译过了就直接提交了 ,喜提 + 倒1
--->
正一 ---> 倒一
· 比赛过程
T1 最开始敲的暴力 ,但是笔记本太垃圾了 的数据
复杂度居然跑了
,于是找了规律 ,推出了
做法
T2 一眼 会炸 ,所以用桶优化 ,笔记本用我
的正解居然跑了
,所以保险起见把
改成了
,结果输入部分一个变量敲错了 ,懒得跑样例了 ,直接提交于是
了
T3 正解思路应该是按位处理 ,没想出来怎么写 ,写的 暴力 ,正常
T4 暴力 ,
· 题目分析
T1【三个(three)】
1、题目大意
有 三种微生物
一秒会繁殖出
个
,
个
,
个
一秒会繁殖出
个
,
个
,
个
一秒会繁殖出
个
,
个
问 秒后
各有多少个
2、赛时思路
循环暴力递推 ,后来发现答案按照每三个一组循环 , 复杂度即可
3、赛时代码&AC代码
#include<bits/stdc++.h>
using namespace std;
long long n;
int main(){
// freopen("three.in","r",stdin);
// freopen("three.out","w",stdout);
cin>>n;
if(n%3==2){
cout<<"even\neven\n";
}
else{
cout<<"odd\nodd\n";
}
if(n%3==1){
cout<<"even";
}
else{
cout<<"odd";
}
fclose(stdin);
fclose(stdout);
return 0;
}
T2【合体(fit)】
1、题目大意
有 个
~
的整数 ,两个
可以合成
,
次询问 ,每次询问给出
,问最多可以合成几个
。
2、赛时思路
因为给出了美俄数字的范围 ,所以开一个桶 ,在询问前处理出每个数字可以被合成几个 ,记为 ,每次输出即可 。
3、赛时代码
#include<bits/stdc++.h>
using namespace std;
int n,m,a[1000005],y,q,x,ans[1000005];
int main(){
freopen("fit.in","r",stdin);
freopen("fit.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]); //万恶的 scanf 66666这个入开桂了 直接把我100pts整没了
a[y]++;
}
for(int i=1;i<=m+1;i++) ans[i]=a[i]+(ans[i-1])/2;
scanf("%d",&q);
while(q--){
scanf("%d",&x);
printf("%d\n",ans[x]);
}
fclose(stdin);
fclose(stdout);
return 0;
}
4、AC代码
#include<bits/stdc++.h>
using namespace std;
int n,m,a[1000005],y,q,x,ans[1000005];
int main(){
freopen("fit.in","r",stdin);
freopen("fit.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&y);
a[y]++;
}
for(int i=1;i<=m+1;i++) ans[i]=a[i]+(ans[i-1])/2;
scanf("%d",&q);
while(q--){
scanf("%d",&x);
printf("%d\n",ans[x]);
}
fclose(stdin);
fclose(stdout);
return 0;
}
T3【矩阵(matrix)】
1、题目描述
的矩阵 ,问矩阵所有子矩阵的异或和的和是多少
2、赛时思路
考虑前四个点 因为异或满足前缀和性质 ,所以可以先二位前缀和算出所有异或和 ,然后枚举子矩阵的左上角和右下角 ,累加求和 ,
可以过掉前四个点的
3、赛时代码
#include<bits/stdc++.h>
using namespace std;
long long n,m,a[305][305],sum[305][305],ans;
int main(){
// freopen("matrix.in","r",stdin);
// freopen("matrix.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&a[i][j]);
sum[i][j]^=sum[i-1][j]^sum[i][j-1]^sum[i-1][j-1]^a[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
for(int I=i;I<=n;I++){
for(int J=j;J<=m;J++){
ans+=sum[I][J]^sum[I][j-1]^sum[i-1][J]^sum[i-1][j-1];
}
}
}
}
printf("%d",ans);
fclose(stdin);
fclose(stdout);
return 0;
}
4、正解思路
枚举起始行 和终止行
,之间的每一列都求异或和
,即
~
的异或和
如果继续枚举两个端点 ,则时间复杂度仍是 ,所以考虑优化 ,可以对
数组求前缀和 ,
数据中有提到 ,所以每次按位处理 ,记录当前区间在之前出现过的
或
的个数如果是偶数 ,则为
,否则为
,累加求即可 ,时间复杂度
5、正解代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,m,a[305][305],ans=0;
int main() {
cin>>n>>m;
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>a[i][j];
for(int i=1;i<=n;i++){
long long x[305]={};
for(int j=i;j<=n;j++){
long long sum[305]={};
for(int k=1;k<=m;k++){
x[k]^=a[i][k];
sum[k]=sum[k-1]^x[k];
}
for(int p=0;p<10;p++){
int cnt[2]={1,0};
for(int k=1;k<=m;k++){
int t=(sum[k]>>p)&1;
ans+=(1<<p)*cnt[t^1];
cnt[t]++;
}
}
}
}
cout<<ans;
return 0;
}
T4【数对(pair)】
1、题目描述
一个长度为 的数列
一个长度为 的数列
按照 的规则生成数组
为生成数组中有多少个逆序对
2、赛时思路
暴力模拟 , 的复杂度可以过掉
3、赛时代码
暴力的代码没啥必要贴了
4、题解思路
可以用归并排序优化 ,过掉
因为
所以可以在输入时
p ,分块求逆序对 ,然后记录当前块之前每个数出现的次数 ,计算块与块间的逆序对 ,再加上每个块本身的逆序对 ,即可得到答案
5、AC代码
#include<bits/stdc++.h>
using namespace std;
unsigned long long n,m,p,a[1000006],b[1000006],cnt[15],ans,dp[10000007],vis[15],sum[15][15];
void write(__int128 x){
if(x>9){
write(x/10);
}
putchar(char(x%10+'0'));
}
int main(){
//freopen("pair.in","r",stdin);
//freopen("pair.out","w",stdout);
cin>>n>>m>>p;
for(int i=1;i<=n;i++)scanf("%d",&a[i]),a[i]%=p;
for(int i=1;i<=m;i++)scanf("%d",&b[i]),b[i]%=p;
for(int i=0;i<p;i++){
memset(vis,0,sizeof vis);
for(int j=1;j<=m;j++){
long long tmp=(i+b[j])%p;
for(int k=tmp+1;k<p;k++){
dp[i]+=vis[k];
}
vis[tmp]++;
sum[i][tmp]++;
}
}
for(int i=1;i<=n;i++){
ans+=dp[a[i]];
for(int j=0;j<p;j++){
for(int k=j+1;k<p;k++){
ans+=sum[a[i]][j]*cnt[k];
}
}
for(int j=0;j<p;j++){
cnt[j]+=sum[a[i]][j];
}
}
write(ans);
fclose(stdin);
fclose(stdout);
return 0;
}
· 赛后总结
每场比赛的策略大致是前两题保证 ,后两题尽量拿分 ,这场比赛前两题敲正解 ,后两题敲暴力 ,期望得分
,但是第二题改了输出没有进行调试就直接提交了 ,导致暴扣
,以后的比赛在改完代码后一定要再跑一遍样例 ,第四题也应该再写个归并多拿十分的 ,明天比赛