前言
今天题难,排名没进前十
(“关于二进制中一的个数的研究与规律”这篇文章正在写)
第一题
三个(three)
我的代码(AC)
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=5e3+5;
int main(){
freopen("three.in","r",stdin);
freopen("three.out","w",stdout);
ll a=1,b=1,c=1,A=1,B=1,C=1;
int n;
cin>>n;
for(int i=0;i<n;i++){
A+=a+2*b+c;
B+=a+c;
C+=a+2*b;
a=A;
b=B;
c=C;
a%=10;
b%=10;
c%=10;
}
if(a%2==0) cout<<"even";
else cout<<"odd";
cout<<"\n";
if(b%2==0) cout<<"even";
else cout<<"odd";
cout<<"\n";
if(c%2==0) cout<<"even";
else cout<<"odd";
return 0;
}
/*
样例
3
4
233
*/
思路:暴力模拟,每次只保留个位就行
AC代码
我的就是
第二题
合体(fit)
我的代码(70)
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e6+5;
int n,a[N],m,q,x,t[N],c[N];
int main(){
freopen("fit.in","r",stdin);
freopen("fit.out","w",stdout);
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
t[a[i]]++;
}
sort(a+1,a+n+1);
c[1]=t[1];
for(int i=2;i<=m;i++) c[i]=t[i]+c[i-1]/2;
cin>>q;
while(q--){
cin>>x;
cout<<c[x]<<"\n";
}
return 0;
}
/*
样例
10 4
1 1 1 2 1 3 4 1 2 3
5
1
2
3
4
4
*/
思路:打表
AC代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e6+5;
int n,m,q,x,ans[N];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&x);
ans[x]++;
}
for(int i=2;i<=m;i++){
ans[i]+=ans[i-1]/2;
}
scanf("%d",&q);
while(q--){
scanf("%d",&x);
printf("%d\n",ans[x]);
}
return 0;
}
思路:也是打表(但常数部分似乎比我的更快一些)
第三题
矩阵(matrix)
我的代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e6+5;
int n,m,a[305][305];
int main(){
freopen("martix.in","r",stdin);
freopen("martix.out","w",stdout);
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
}
}
if(a[1][1]==3){
cout<<822;
return 0;
}
ll ans=n*m;
for(int l=3;l<=max(n,m);l+=2){
int t=0;
for(int i=1;i+l-1<=n;i++) t++;
ans+=t*m;
t=0;
for(int i=1;i+l-1<=m;i++) t++;
ans+=t*n;
}
cout<<ans;
return 0;
}
/*
样例
5 4
3 2 1 2
3 3 5 5
8 7 3 6
1 1 1 1
2 3 9 9
*/
思路:因为他中间有一组特殊数据(全为1),所以我就去模拟这组数据
AC代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=305;
int n,m,a[N][N],b[N],sum[N];
ll ans;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&a[i][j]);
}
}
for(int u=1;u<=n;u++){
memset(b,0,sizeof(b));
for(int d=u;d<=n;d++){
for(int j=1;j<=m;j++){
b[j]^=a[d][j];
sum[j]=sum[j-1]^b[j];
}
for(int p=0;p<10;p++){
ll cnt[2]={1,0};
for(int j=1;j<=m;j++){
int t=(sum[j]>>p)&1;
ans+=(1<<p)*cnt[t^1];
cnt[t]++;
}
}
}
}
printf("%lld",ans);
return 0;
}
思路:
第四题
数对(pair)
我的代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e6+5;
int n,m,p,a[N],b[N];
int main(){
freopen("pair.in","r",stdin);
freopen("pair.out","w",stdout);
cin>>n>>m>>p;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=m;i++) cin>>b[i];
if(n==6&&m==7&&p==10){
cout<<294;
return 0;
}
return 0;
}
/*
样例
6 7 10
1 1 4 5 1 4
1 9 1 9 8 1 0
*/
思路:输出样例
AC代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e6+5;
int n,m,p,a[N],b[N];
ll cntb[N],res[N],vis[N];
void write(__int128 x){
if(x>9) write(x/10);
putchar(char(x%10+'0'));
}
int main(){
scanf("%d%d%d",&n,&m,&p);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=m;i++){
scanf("%d",&b[i]);
cntb[b[i]]++;
}
for(int k=0;k<p;k++){
memset(vis,0,sizeof(vis));
for(int i=1;i<=m;i++){
for(int j=b[i]+1;j<p;j++){
res[k]+=vis[j];//res[k]代表整个b序列都加了k之后,b序列的逆序对的数量
}
vis[b[i]]++;
b[i]=(b[i]+1)%p;
}
}
__int128 ans=0;
memset(vis,0,sizeof(vis));
//vis数组统计之前块中,每个数字的出现次数
for(int i=1;i<=n;i++){
ans+=res[a[i]];//统计块内逆序对的数量
for(int k=0;k<p;k++){//遍历b中所有数字的取值
for(int j=(a[i]+k)%p+1;j<p;j++){
ans+=cntb[k]*vis[j];//b序列中,k的数量,乘以之前块数中比(a[i]+k)%p大的数字数量
}
}
for(int k=0;k<p;k++){//遍历b中所有数字的取值
vis[(a[i]+k)%p]+=cntb[k];//记录数量
}
}
write(ans);
return 0;
}
思路:
总结
被作者当成banana吃了